SSY
SSY

Reputation: 41

Displaying a message when a certain array element is present in C

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

Upvotes: 1

Views: 71

Answers (3)

user9706
user9706

Reputation:

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
}

which is specialization of memchr():

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

Upvotes: 1

Madagascar
Madagascar

Reputation: 7345

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.

Upvotes: 1

Some programmer dude
Some programmer dude

Reputation: 409374

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.

Upvotes: 4

Related Questions