If statement for structure - c

I have to write if statement for structure for person which:
Is older or equal 16 and younger or equal 20
First letter of name and surname must be 's' or 'n'
My code:
if(x.name[0]=='s' ||
x.name[0]=='n' &&
x.surname[0]=='s' ||
x.surname[0]=='n' &&
(x.age>=16 && x.age<=20))
{
/* print person */
}
I want just to print out these persons, but code prints non-compliant ages.
What is wrong with the condition?

Enclose each || section in brackets. Keep in mind && has higher priority than ||. Like so:
if((x.name[0]=='s' || x.name[0]=='n') &&
(x.surname[0]=='s' || x.surname[0]=='n') &&
(x.age>=16 && x.age<=20))
Splitting the code on several lines is not needed it just makes the code more readable.

This should work:
(x.name[0]=='s' || x.name[0]=='n') && (x.surname[0]=='s' || x.surname[0]=='n') && (x.age>=16 && x.age<=20)
Additional pair of () added. Also, You know that such a cumbersome statements are considered to be a really bad practice?

Your missing parenthesis around the name and surname conditions
if((x.name[0]=='s' || x.name[0]=='n') && (x.surname[0]=='s' || x.surname[0]=='n') && (x.age>=16 && x.age<=20))

On seeing the statement
if(x.name[0]=='s' ||
x.name[0]=='n' &&
x.surname[0]=='s' ||
x.surname[0]=='n' &&
(x.age>=16 && x.age<=20))
compiler interpret it as
if(x.name[0]=='s' || (x.name[0]=='n' && x.surname[0]=='s') ||
(x.surname[0]=='n' && x.age>=16) && x.age<=20))
The reason behind this is, logical operator && has higher precedence than that of logical || operator. What does it mean then?
It means that the expression (sub-expression) get bound more closely to && than that of ||.
Take a small example to understand this
#include <stdio.h>
int main(void)
{
int i = 1, j = 1, k = 1;
printf("%d ", i++ || ++j && ++k);
printf("%d %d %d", i, j, k);
return 0;
}
The output of this program is:
1
2 1 1
On first look a novice may think that the output is wrong and it should be
1
2 1 2
by thinking that i++ || ++j && ++k is same as (i++ || ++j) && ++k but this is not true. Because of the higher precedence of && over ||, sub-expressions j++ and k++ bound to && and it will be interpreted by the compiler as i++ || (++j && ++k)

Related

Why no brackets needed among conditions in if sentence?

int num;
scanf("%d", &num);
if (num % 4 == 0 && num%100 != 0 || num % 400 == 0)
printf("%d", 1);
else
printf("%d", 0);
In this logic, I found I do not need to do () in AND condition which is in front of OR condition.
if (*(num % 4 == 0 && num%100 != 0)* || num % 400 == 0)
It's only needed if (num % 4 == 0 && num%100 != 0 || num % 400 == 0) without () in front of OR condition.
so, it seems (A && B || C) works like ((A && B) || C)
but it seemed it could work as (A && (B || C)) condition.
Why is () not needed in this situation? A and B condition are automatically grouped from the beginning?
All operators in C (and in fact all languages) have what's called operator precedence which dictates which operands are grouped first.
The logical AND operator && has a higher precedence than the logical OR operator ||, which means that this:
A && B || C
Is the same as this:
(A && B) || C
So if you want B || C to be grouped together, you need to explicitly add parenthesis, i.e.:
A && (B || C)
Parentheses decide order of operations, if you move the parentheses around you may change what the output is. In the same way that (A + B) / C is different from A + (B / C) but still a valid equation.
See Order of Operations in C
Logical AND has higher priority than OR:
https://en.cppreference.com/w/c/language/operator_precedence
dg

Problem while defining conditions for multiple variables in C

I'm trying to write a program in C that receives three integers and uses This Method
But I only want the inputs to be in the range of 1-100 (including 1 and 100)
#include <stdio.h>
int main(){
int a , b , c = 50;
do{
scanf("%d %d %d", &a, &b, &c);
}
while((a > 100 || a < 1)&& (b > 100 || b < 1) && (c > 100 || c < 1));
if (a+b > c && a+c>b && b+c>a){
printf("%d\n", a+b+c);
}
else {
printf("invalid\n");
}
And it somehow doesn't consider the conditions
for example if I enter something like 1000 -5 4 It won't reprompt me for a new input
But the weird thing is that if i only consider one of the conditions it will work fine with that one variable! for example if i put something like while((a > 100 || a < 1); in there, it will then reject an input like 1000 2 4
How do I make it that it considers the conditions for all the variables?
Any help would be appreciated!
To check for any of the variable for range, change
while((a > 100 || a < 1)&& (b > 100 || b < 1) && (c > 100 || c < 1));
^^
// Will produce a FALSE value if 'a' is within expected range, and due to
// short-circuit, it'll not evaluate other conditions.
to
while((a > 100 || a < 1) || (b > 100 || b < 1) || (c > 100 || c < 1));
That said, couple of other points:
int a , b , c = 50; only initializes c, other variables are uninitialised and contain indeterminate values. Be a little more explicit, declare and define each variable in separate line (not a technical requirement, sake of readability and maintainability while being technically correct).
Always check for the success of scanf(), before using the scanned values. Better, do away with scanf() for user inputs and use fgets() instead.
more readable :
while(!( 1 <= a && a <= 100 && 1 <= b && b <= 100 && 1 <= c && c <= 100));
Your loop will only continue if all three of a, b, and c are out of range - in your example of 1000 -5 4, the condition (c > 100 || c < 1) evaluates to false (0), so the whole expression evaluates to false and the loop exits.
You need to change the sense of the test, such that it will continue if any of a, b, or c are out of range. There are a couple of ways to do this:
while ( (a < 1 || a > 100) || (b < 1 || b > 100) || (c < 1 || c > 100) );
Changing the && to || means that the expression will evaluate to true and the loop will continue if any one of a, b, or c are out of range.
Another option:
while ( !(1 <= a && a <= 100) && (1 <= b && b <= 100) && (1 <= c && c <= 100 ) );
This will cause the loop to exit if all three of a, b, and c are in range.
You should also check the result of scanf to make sure you read all 3 inputs:
do
{
if ( scanf ( "%d %d %d", &a, &b, &c ) != 3 ) )
{
if ( feof( stdin ) || ferror( stdin ) )
{
fputs( "Error or EOF on input, exiting", stderr );
return EXIT_FAILURE;
}
else
{
fputs( "Bad input detected, clearing input stream", stderr );
/**
* Read and discard everything up to the next newline character
*/
while ( getchar() != '\n' )
; // empty loop
/**
* Unconditionally branch back to the beginning of the loop since
* at least one of a, b, and c wasn't read at all (i.e., don't
* rely on the test since what you're testing isn't valid).
*/
continue;
}
}
} while ( (a < 1 || a > 100) || (b < 1 || b > 100) || (c < 1 || c > 100 ) );

Why does this following program print "Yes" instead of "No"?

Why does this following program print "Yes" instead of "No"?
None of the variables is initialized to 2.
bool hello = 0;
int a = 1;
int b = 3;
int c = 4;
int d = 5;
if (a || b || c || d == 2) {
hello = 1;
}
if (hello == 1) {
printf("Yes");
}
if (hello == 0) {
printf("No");
}
return 0;
}
The statement
if (a || b || c || d == 2)
is equivalent to:
if (a != 0 || b != 0 || c != 0 || d == 2)
The equality comparison does not automatically distribute across all the variables. If you want to do that, you need to perform all the comparisons explicitly:
if (a == 2 || b == 2 || c ==2 || d == 2)
The expression (a || b || c || d == 2) evalutates to true because it treats a, b, c as booleans, and any non-zero integer is true.
You have given logical operator in the expression It means that if non zero value came then the expression is true. Then hello=1 is set and in next f statement it prints YES
You just meet the short circuit behavior of logical expressions OR.
The order of evaluation of logical OR || is left to right.
So in the following expression:
left || right
if left = true then right will never going to be executed (short circuit). In your code exactly same happened.
As you know, any non zero value treated as true in C, hence, a which is 1 is true. So, take a look:
if (a || b || c || d == 2)
if (true || bla bla bla) //rights are not even checked!
if (true)
hello = 1;
Tada! So the program print "Yes"!
None of the variables is initialized to 2.
Yes of course! But your if condition is not going to check that. To do so, try this:
if (a == 2 || b == 2 || c ==2 || d == 2) {
//...
because if judge num is not zero , if think this is true. so your code
if (a || b || c || d == 2)
like
if ( true || true || true || false)
the result is true, programe print "YES"

Output of the below C Code [duplicate]

This question already has answers here:
Short circuit evaluation and side effects [duplicate]
(3 answers)
Closed 8 years ago.
int i=-1,j=-1,k=0,l=2,m;
m=l++||i++ && j++ && k++;
printf("%d %d %d %d %d",i,j,k,l,m);
Output of the code is: -1 -1 0 3 -1
My question is why i++ j++ and k++ is not being evaluated even when && has a higher priority over || ?
See
Short-circuit evaluation.
Essentially what's happening is that as l++=3 which is not 0, it evaluates to True (only 0 would be False). Thus, the second part of the expression after || is not evaluated.
Think
m=l++||i++ && j++ && k++;
as
m = ( (l++)|| ( (i++ && j++) && (k++) ) );
As you know && has higher operator precedence, therefore i++ && j++ && k++ will be grouped as (i++ && j++) && k++ and then ( (i++ && j++) && (k++) ).
Because of the short-circuit behavior of ||, after evaluating l++, which is true and therefore the right operand ( (i++ && j++) && (k++) ) of || is not evaluated.

"lvalue required as left operand of assignment " error

The following code produces a "lvalue required as left operand of assignment"
if( c >= 'A' && c <= 'Z' || c = " " || c = ",") {
I assume I'm writing this wrong, what is wrong? and how would I write it correctly?
You should use single quotes for chars and do double equals for equality (otherwise it changes the value of c)
if( c >= 'A' && c <= 'Z' || c == ' ' || c == ',') {
Furthermore, you might consider something like this to make your boolean logic more clear:
if( (c >= 'A' && c <= 'Z') || c == ' ' || c == ',') {
Although your boolean logic structure works equivalently (&& takes precedence over ||), things like this might trip you up in the future.
equality is ==, = is assignment. You want to use ==. Also "" is a char*, single quotes do a character.
Also, adding some parens to your condition would make your code much easier to read. Like so
((x == 'c' && y == 'b') || (z == ',') || (z == ' '))
= is the assigning operator, not the comparing operator. You are looking for ==.
Personally, I prefer the minimalist style:
((x == 'c' && y == 'b') || (z == ',') || (z == ' '))
( x == 'c' && y == 'b' || z == ',' || z == ' ' )
or
( x == 'c' && y == 'b' ? z == ',' : z == ' ' )
against
( x == 'c' && y == 'b' ? z == ',' : z == ' ')

Resources