What does a ! operator mean in front of a variable? - c

I have just a simple question, I'm learning C programming and I know that the ! operator means logical NOT. My question is that what does it mean in this case in a do while cycle as a condition?
Is it checking somehow if the variable is changed?
I know I should probably find it somehow, but when I try to google '!'s it doesn't want to show what I meant.
#include <stdio.h>
int main() {
int input, ok=0;
do {
scanf("%d", &input);
if ( /* condition */) {
//the input is wrong it will scan another one
}
else {
//the input is correct, so the while cycle can stop
//we don't need more inputs
ok = 1;
}
} while (!ok);
//...
//...
//...
return 0;
}

!ok is the same as ok == 0.
Remember that in C, any non-zero scalar value in a Boolean context means "true" while zero means "false". It's a common C idiom to write !foo instead of foo == 0. It works for pointers as well:
FILE *foo = fopen( "some_file", "r" );
if ( !foo )
{
fprintf( stderr, "could not open some_file\n" );
return EXIT_FAILURE;
}
So, while ( x ) is the same as while ( x != 0 ), and while ( !x ) is the same as while ( x == 0 ).

Speaking loosely, the given code executes the contents of the loop repeatedly "while NOT ok", meaning "while OK is zero". In the else block, ok is set to 1, meaning that the loop will not repeat again.
More formally, !ok is an expression that is true when ok is equal to zero, and false when ok is any value other than zero.

In the context of logical operations, anything except zero (*) is true, zero is false.
so !1 is "! true" is false
!0 is "! false" is true
(*) any kind of zero: NULL counts as zero, 0.0 counts as zero

Just think about it, the ok has a Boolean value, which is false at the initialisation.
(In c, 0 has a false value, I assume that you know this.)
In the do while, it is simply negates the logical value, it still means a NOT. If the condition is true, it will loop, otherwise, won't.
If ok has a false value and you'll negate it, it will have a true value, the loop will, umm loop.
I hope you'll get the point, it does not have any other meanings.

Related

How would a compiler interpret `if(!(a=10))`?

I have a homework assignment in which I believe the professor has made a typo, typing if(!(a=10)) instead of if(!(a==10)). However, when asked if this was typo, she told me to "assume that the equations are correct and give your answer." Specifically, the assignment is to describe the behavior of the program:
#include <stdio.h>
int main() {
int a = 100;
while (1) {
if (!(a=10)) {
break;
}
}
return 0;
}
If the offensive code read (!(a==10)) then the program would enter the if loop, reach the break and exit both loops, which makes sense for a beginner-level course in C programming.
However, if, truly, the code is meant to read (!(a=10)) then I don't know what the compiler will interpret that to mean. I do know that the code compiles, and when you run it in UNIX, it just allows you to input whatever you want using the keyboard, like say the number "7", and then you press enter and it moves to a new line, and you can enter "dog", and move to a new line, and on and on and it never exits back to the command line. So (1) how would the compiler interpret (!(a=10))? And (2) why does the program allow you to just continue to input entries forever?
Thanks!
For the first question,
What's the meaning of if( !(a=10) ){break;},
It's equivalent to
a = 10; if(!a) {break;}
For a value of 10 !a will be 0 and it never breaks the while loop.
In this particular example, if you assign if(!(a=0)), then it will exit the loop;
For the second question, there is no code present in your example.
But first question's answer can be extended here as the loop never breaks it keeps on asking the input values.
From the C Standard (6.5.3.3 Unary arithmetic operators ΒΆ5)
5 The result of the logical negation operator ! is 0 if the value of
its operand compares unequal to 0, 1 if the value of its operand
compares equal to 0. The result has type int. The expression !E is
equivalent to (0==E).
So according to the quote the if statement
if (!(a=10)) {
is equivalent to
if ( ( a = 10 ) == 0 ) {
As the value of the assignment sub-expression, a = 10 is equal to 10 that is it is not equal to 0 then the condition of the if statement evaluates to logical false and the sub-statement of the if statement will not get the control and you will have an infinite while loop.
In fact, you can rewrite this while loop
while (1) {
if (!(a=10)) {
break;
}
}
the following way with the same effect
while ( ( a = 10 ) ) {}
or just
while ( ( a = 10 ) );
or more simply:
while ( a != 0 );
because what is important is that within the while loop the variable a does become equal to 0.
while (1) {
if (!(a=10)) {
break;
}
}
as !(a = 10) is always zero (false) it is equivalent of:
while (1) {
}

Evaluation of the if condition in c as true or false

int n,i;
scanf("%d",&n);
if(n==0)
printf("a");
else if (!(n>=1))
printf("b");
When I give the input as m, the condition (n==0) is evaluating to be true. When the condition is a valid expression and non-zero, then it's true. When I am replacing n by i and providing the same input, the condition n==0 is getting evaluated as false. Why is this happening?. Why is it evaluating to be true even when there's 0 in n==0 ?
The definition of scanf() says nothing about what it will do to the value of arguments that cannot be assigned, but invariably in practice, it leaves them untouched.
In this case both n and i are unitialised and may contain any value - in your case n happened to contain zero at the moment you tried it, but that is not a given - it is undefined. The C runtime is not required to initialise variables with auto storage class (local, non-static) to zero.
int n = 0;
int i = 0;
Note also that sscanf() returns the number of format specifiers that result in a successful assignment, so you can for example:
while( scanf("%d",&n) == 0 )
{
// wait until valid input
}
This is strictly safer than relying only initialisation of a "default" value because scanf() strictly makes no guarantees that it will not modify an argument in any case - it would only be an unusual implementation that did so. Also in practice you would normally want to handle erroneous input one way or another rather then simply ignore it and use a default. A safe and unambiguous way of providing a default if required is:
if( scanf("%d",&n) == 0 )
{
n = 0 ;
}

What does the exclamation point in if (!strcmp() ... do?

Can someone explain what the exclamation point in the if statement does (i.e. !strmcp)?
string names[] = {"EMMA", "RODRIGO", "BRIAN", "DAVID"};
// Search for EMMA
for (int i = 0; i < 4; i++)
{
if (!strcmp(names[i], "EMMA"))
{
printf("Found\n");
return 0;
}
}
printf("Not found\n");
return 1;
For an if statement, if the expression evaluates to 0, then the block of code following the if statement is not executed. Any other value (positive or negative), will result in executing the code block. The function strcmp uses 0 to say that strings are equal because less than 0 is used to differ from greater than 0.
So in this code, we want printf("Found\n"); to be executed when the strings are equal. Since strcmp results in 0, we need to negate the value so that it becomes 1 which will result in executing that code block.
strcmp() returns 0 if the strings are identical, so you need to negate it, if you use it in an if clause to assert a true statement.
If your clause is if(0), the code inside the condition will not be executed.
For completion, it returns negative if the first different character found is lower in the first string, for instance:
first parameter string: "abca"
second parameter string :abcd"
This will return negative. If it's the other way arround it will return positive.
Also, string is not usually used in C (I refer you to Jonathan Leffler's commment), you can use char*:
char *names[] = {"EMMA", "RODRIGO", "BRIAN", "DAVID"};
Unary operator ! is called the logical NOT operator (cf., for example, this definition at cppreference.com). ! expression returns 1 if expression evaluates to 0, and it returns 0 if expression evaluates to anything else but 0.
So the condition in if (!0) gives 1; this means, the condition is met and the if-block is entered. It has the same meaning as if(0==0)
Consequently, the meaning of
if(!strcmp(names[i], "EMMA"))
in your code is exactly the same as
if(0==strcmp(names[i], "EMMA"))
And you already know when strcmp returns 0...
The exclamation point is the C's boolean negation character.
It means give me the boolean opposite of the value. A boolean is either true or false, which are 1 or 0 in the C Language.
In C, if statements execute their conditional statements if the argument is true.
if (a) means if a is true (i.e. non-zero)
if (!a) means if a is false (i.e. 0)
Therefore:
if (a) is the same as if (a != 0)
if (!a) is the same as if (a == 0)
Sometimes you'll see code that uses two exclamation points in a row "!!"
For example:
int a = !!b;
That ensures a will be ONLY 0 or 1, regardless of what the value of b is.
If b is ANY non-zero value, the ! operator will treat it as though it is true true, which it treats as being the same as 1
So:
!0 == 1
!1 == 0
!52 == 0
!25692 == 0
The second ! does the boolean inversion again, so:
!!0 == 0
!!1 == 1
!!52 == 1
!!25692 == 1
In C any non zero value is considered ad the logical truth, zero i considered as logical false. ! is a logical negation. So !0 (not false) will be the truth and if(!strcmp(str1,str2)) {statements} statements will be executed when str1 will be same as str2

Working of Nested IF-Else Without the Braces

Can someone please explain me the working of Nested If-Else Statements written WITHOUT the Curly Braces.
I want to understand why Below Programme isn't giving me any output.
I've checked for all the 4 possibilities.
(Outer-If, Inner-If)::(True, True),(True, False),(False, True),(False, False).
I'm editing with CodeBlocks,using gcc compiler on Windows.
int main()
{
int n=0,m=0;
if ( n > 0 )
if ( m > 0 )
printf("Inner-If Condition satisfied.");
else
printf("Inner-If condition not satisfied. ");
return 0;
}
Thank You.
They work as-if there was a curly brace around the following statement. In your case then:
if ( n = 0 ){ // ToDo - did you mean `==`, `n = 0` is `0`.
if ( m = 0 ){ // ToDo - ditto.
printf("True");
} else {
printf("False");
}
}
In your case I think the bewilderment stems from your using = rather than ==.
The if-else ambiguity is solved by defining that an ambiguous else belongs to the nearest if.
The parser will see an ambiguity, however, the parser has ben adapted to solve the ambiguity as described above (e.g. yacc).
Note: the reason your program does not give any output is because n=0 (an assignment) results in n being zero and so the test becomes false, so the branch is not taken and the return is executed.
n = 0 is an assignment in C. It assigns n the value 0. Assignments also evaluate to the value that is assigned, so here, to 0, which is in a boolean context false -- so your outer if is always false.
To compare two values, use == instead, which evaluates to 1 (true) on equality, 0 (false) on inequality. *)
Your assumption about if and else was correct, the reason you don't see output is just your wrong attempt at comparing values.
A good compiler will warn you of such typos. E.g. with gcc, enable a reasonable set of warnings with -std=c11 -Wall -Wextra.
*) as a side note, in a boolean context, a zero value is false and any other value is true, so you could also write the code like this (! is logical not, inverting true and false):
if (!n)
if (!m)
// ...
Whether this is good style depends on who you ask. I personally like to write it this way if 0 semantically represents the lack of a value, or if the variable is already meant as a boolean value. Then "if not n" sounds kind of natural.
Use == inside if Statement. such as below mentioned code will work.
if ( n == 0 )
if ( m == 0 )
printf("True");
else printf("False");

two initialisations seperated by seperated by semi colon in C

for(i=1;i=-1;i++)
if(i<5) break;
printf("%d\n",i);
i was asked to write the output of the following code, i could not understand as the second argument should have been a condition, but here it was an assignment,
output: -1
i cant understand how it is possible, so i tried to experiment with the code
int i=1;
while(i=-1)
{
printf("condition is true\n");
if(i<5) break;
}
printf("%d\n",i);
the output of the following code is
output: condition is true
-1
can anyone explain how the above two codes work
and how is while(i=-1) evaluated to TRUE??
The condition is always true. Because the value of an assignment statement is the value assigned. So -1 is non-zero and non-zero value is considered as true in c so it is always true.
The correct usage would be == which compares the value and returns 1 or 0 based on the equality or non-equality.
So here when you did i = -1 and put in the while loop condition - it boils down to
while( -1 ){
...
/* break here */
}
And as -1 is considered as true in c because of it being nonzero - the loop condition evaluates to true.
The break statement here is given here so that this loop doesn't turn to be an infinite loop.
The syntax of a for loop in C is
for(expr1, expr2; expr3)
/* body of loop */
Now, conventionally, expr1 is the loop initialization, and expr2 is the condition under which to keep going, and expr3 is the increment between loops. But that's only a convention -- in actuality, the compiler just arranges to execute expr1 once, then expr2 to decide whether to take another trip through the loop or not, then expr3 at the bottom of the loop. So it's more or less equivalent to
expr1;
while(expr2) {
/* body of loop */
expr3;
}
Or, stated another way:
expr1;
while(1) {
if(!expr2) break;
/* body of loop */
expr3;
}
But then the other key point is that, yes, the expression
i = -1
doesn't look much like a condition; it looks like an assignment. But in C, when you use an expression as a condition (that is, in a context where what we care about is whether the expression is "false" or "true", all we really care about is whether the expression evaluates to zero or to non-zero. And the value of an assignment expression is simply the value that was assigned. So the value of
i = -1
is -1, and that's not zero, so it's interpreted as "true". So if you say
while(i = -1) {
/* body of loop */
}
the condition is always "true", so it will be an infinite loop, unless there's a break statement in the body somewhere (or a return, or a call to exit(), or something like that).
First for loop one does nothing and will be removed from the generated code if the optimisation is on
Second one enters the loop one time. The actual loop will be removed by the optimising compiler and replaced by the puts, initialisation and printf call.
https://godbolt.org/g/T5wgqt
printf with the format string only is replaced by the puts

Resources