Rishu
Rishu

Reputation: 77

Why can't I check multiple conditions using only 1 equality operator in C?

In my code below, a is an character array and my if statement is checking whether a particular character is A,D,O,Q,R or P.

The conventional way of checking condition in if condition is as shown in code below.

/Code Snippet/

scanf("%s",a);
len=strlen(a);
for(i=0;i<len;i++)
{
        if(a[i]=='A'||a[i]=='D'||a[i]=='O'||a[i]=='Q'||a[i]=='R'||a[i]=='P')
             //Do something
}           

My Doubt:

1) Let' say I write if statement like this :

if(a[i]=='A'||'D'||'O'||'Q'||'R'||'P')

Why doesn't it behave in the same way as my if statement behaved in above code snippet? How does this statement work?

2) What if I want to check multiple condition(lets say hundreds or thousands of them), how can I check using just one equality operator and don't have to use multiple equality operator like this :

if(a[i]=='A'||a[i]=='D'||a[i]=='O'||a[i]=='Q'||a[i]=='R'||a[i]=='P')

Can it be done? If yes,How? If not,why?

Upvotes: 0

Views: 2160

Answers (5)

user3386109
user3386109

Reputation: 34829

2) You can use a lookup table to determine whether a character is within a given set with a single comparison. This is in fact how some compilers implement the isupper isalpha and related functions/macros defined by <ctype.h>.

The cost is that you either need to hand code a table of 256 entries, or you need code to fill in the table at runtime. This also assumes that you aren't concerned with unicode characters, since that makes the table a whole lot bigger.

The following code initializes the table at startup, and defines a macro that allows you to check whether a character is in the set {'A', 'D', 'O', 'Q', 'R', 'P'} without even using one equality operator.

#include <stdio.h>
#include <string.h>

#define isSpecial(x) (specialArray[x])

char specialArray[256];
int specialList[] = { 'A', 'D', 'O', 'Q', 'R', 'P', EOF };

int main( void )
{
    memset( specialArray, 0, sizeof(specialArray) );
    for ( int i = 0; specialList[i] != EOF; i++ )
        specialArray[specialList[i]] = 1;

    if ( isSpecial( 'A' ) )
        printf( "A is special\n" );
    else
        printf( "A is normal\n" );

    if ( isSpecial( 'B' ) )
        printf( "B is special\n" );
    else
        printf( "B is normal\n" );
}

Upvotes: 0

linluk
linluk

Reputation: 1670

in c every not null value evaluates to true.

when you write this:

if(a[i]=='A'||'D'||'O'||'Q'||'R'||'P')

you can think of it like this:

if(a[i]=='A' || true || true , ...)

so your statement will always be true!

there are more posibilitys to do such checks, it depends which one is best:

switch(a[i]) {
  case 'A':
  case 'D':
  case 'O':
  case 'Q':
  case 'R':
  case 'P':
    // your if code here
    break;
  default:
    // your else code here
    break;
}

or

char check[6] = {'A','D','O','Q','R','P'};
for(int j = 0; j < 6; j++)
  if(check[j]==a[i]) {
    // your code
    break;
  }

or if you can group the values:

if(a[i] > 'A' && a[i] < 'D' || a[i] > 'P' && a[i] < 'T')  // warning! other values, just for demo!

and many more.

Upvotes: 2

Sourav Ghosh
Sourav Ghosh

Reputation: 134286

Two things to check,

  1. Operator Precedence, which tells == has higher precedence over ||

  2. The || operator itself, which mandates [chapter 6.5.14, C99]

the || operator guarantees left-to-right evaluation; there is a sequence point after the evaluation of the first operand. If the first operand compares unequal to 0, the second operand is not evaluated.

Answer 1)

So, for an expression like

if(a[i]=='A'||'D'||'O'||'Q'||'R'||'P')

the evaluation will go like,

  1. if a[i]=='A' is TRUE, then if returns TRUE/ success, other operands are not evaluated.

or

  1. if a[i]=='A', is FALSE, then check the next operand which is D [ASCII value] which evaluates to TRUE always.

Either way, there is only one comparison made with a[i] value. Other operands of || are , well, just values. There's no comparison involved.

Answer 2)

So there's no way you can use a single == to check for the (in)equality with multiple values. However, you can make use of a switch statement instead.

If the value of a[i] matches any of the cases, the desired code block will be executed.

switch (a[i])
  case 'A':
  case 'D':
  case 'O':
  case 'Q':
  case 'R':
  case 'P':
            //some code
            break;

Upvotes: 3

You can add your characters of interest to an array like so:

#include <stdio.h>

int main(){
    char a[10] = { 0 };
    printf("enter string sequence:");
    scanf("%s", a);
    int len = sizeof(a)/sizeof(a[0]);
    char review[] = { 'A','D','O','Q','R','P' };
    int rLen = sizeof(review) / sizeof(review[0]);
    int found = 0;
    for (int i = 0; i<len; i++)
    {
        for (int j = 0; j < rLen; j++){
            if (a[i] == review[j]){
                printf("found atlast !!!");
                found = 1;
                break;
            }
        }
        if (found == 1)
            break;
    }
    if (found == 0)
        printf("Could not be found");
}

By using an array like this: char review[] = { 'A','D','O','Q','R','P' };, it becomes very easy to keep track of what is checked.

And as your code requires to change the characters to be reviewed, you will need to make change in just one place.

Upvotes: 0

Gopi
Gopi

Reputation: 19864

a[i]=='A'

The == operator works on the operands on LHS and RHS so if you have

(a[i] == 'A' || 'B' ||......)

Then == will treat that a[i] == 'A' and if that turns out to be TRUE the rest of the operands are not evaluated as (1 || 0 == 1)

The answer is you just can't use a single == operator to check multiple conditions.

Upvotes: 1

Related Questions