Home > Net >  Displaying a message when a certain array element is present in C
Displaying a message when a certain array element is present in C

Time:01-24

This program displays certain messages when some of the elements are 'y' or if all of the elements are 'n'.

My question is about this line: someElements |= array[i] == 'y'. I understand that it can be written in this way: someElements = someElements | array[i] == 'y'.

I'm just asking for an explanation why does it work?

#include <stdio.h>

int main()
{
    
    char array[3] = { 0 };

    int i;
    for (i = 0; i < 3; i  ) {
        do {
        printf("\nElement No.%d [y/n]: ", i   1);
        scanf(" %c", &array[i]);
            if (array[i] != 'y' && array[i] != 'n') {
            printf("Must be a lowercase 'y' or 'n'\n");
            } 
        } while (array[i] != 'y' && array[i] != 'n');
    }

    int someElements = 0;
    
    for (i = 0; i < 3; i  ) {
        someElements |= array[i] == 'y';
    }
    if (someElements) {
        printf("\nSOME of the elements = y.\n");
    }
    else{
         printf("\nNONE of the elements = y.\n");
    }

    return 0;
}

Code link

CodePudding user response:

The result of array[i] == 'y' is a boolean true or false. It can be implicitly converted to the int value 1 or 0 (respectively).

Then it's easy to create a bitwise OR table for the possible combinations of someElements | array[i] == 'y':

someElements array[i] == 'y' someElements | array[i] == 'y'
0 0 0
0 1 1
1 0 1
1 1 1

So if any of the values are 1 then the result will be 1.

From this follows that if any of the characters in the array is equal to 'y' then the end result of someElements after the loop will be 1. Which then can be implicitly converted back to a boolean true in the following if condition.

CodePudding user response:

Bitwise OR:

Returns true if either bit is true.

Truth table:

A | B | A | B
-------------
0 | 0 | 0
1 | 0 | 1
0 | 1 | 1
1 | 1 | 1

From this, we can conclude that

someElements = someElements | array[i] == 'y;

as someElements has been initialized with 0, or false, it will remain false until array[i] = 'y' returns 1, or true.


Aside: On the last iteration, i 1 would access out of bounds memory.

CodePudding user response:

The key insight is for a given binary value x:

  1. 0 | x == x
  2. 1 | x == 1

We initialize the variable someElemenets to 0 (false) so we are in the first case. someElemenets will remain 0 till we encounter an 'y' in the array. It now becomes 1 and will remain so irregardless of the remaining input. Think of it as a one-way (light) switch.

You could just terminate the loop early instead:

 someElements = 0;
 for (i = 0; i < 3 && !someElements; i  ) {
        someElements = array[i] == 'y';
 }

and it even clearer if you write it as a function:

int any_y(size_t n, const char array[n]) {
   for(size_t i = 0; i < n; i  )
      if(array[i] == 'y') return 1
   return 0
}

or just do:

someElements = memchr(array, 'y', 3);
  • Related