0

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?

3
  • Are you asking why the language specifies this particular behaviour? Commented Jan 17, 2015 at 9:01
  • Use a switch statement. Commented Jan 17, 2015 at 9:04
  • 1
    You can match a character against various letters with strchr from <string.h>: if (strchr("aeiou", c)) puts("Vowel!"); Commented Jan 17, 2015 at 9:22

5 Answers 5

3

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;
Sign up to request clarification or add additional context in comments.

2 Comments

1) U wrote: if a[i]=='A', is FALSE, then check the next operand which is D [ASCII value] which evaluates to TRUE always. Why it is "TRUE "always? 2)Lets consider hypothetical situation where || has high precedence than ==, how will the behavior of program change?
@Rishu 1) non-zero values are considered TRUE, check the ASCII value of D. 2) no need to be hypothetical, consider if(a[i]== ('A'||'D'||'O'||'Q'||'R'||'P')), here, it will be equivalent toif (a[i] == 1), because A is always TRUE
2

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.

6 Comments

if(a[i]=='A' || true || true , ...) Why does it assume all other values to be "true" & why doesn't it check for each one of other operands after ||.Suppose I enter a[i]='z', then it checks for 'A',it gives false, then it goes to next operand which you said it will be considered as true always.Why it is so?
@Rishu because they are ascii literals, that means they are numeric values 0..127(255) and every value except NULL and 0 is treated as true. in c there are no booleans. try if(0), if(1), if(42) and if(-23) and see whats happen. and then try this: int a = 'a'; printf("%d",a);.
@Rishu As already said in my answer if you have a || operator and the first condition turns out to be TRUE then rest of the conditions are just ignored because 1 || 0 =1 and 1 || 1 = 1
here you can read more about what @Gopi said: en.wikipedia.org/wiki/Short-circuit_evaluation
@Gopi : Here, I was asking if the condition turns out false,then what?
|
1
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.

3 Comments

Isn't the question why?
@juanchopanza Read my answer where I say the == operator evaluates between two operands and to check multiple conditions you can't have single == operator. I think I have put it right in my answer
I read your answer. This doesn't really say why this is. But the question is unclear anyway.
0

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.

Comments

0

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" );
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.