{
int i=0;
int j;
j=(i=0)?2:3;
printf("the answer is %d",j);
}
I want to know why this statement j=(i=0)?2:3; gives the answer 3 when the value define to i is zero?
In C, zero is considered as false and all non-zero numbers are considered as true. This:
j=(i=0)?2:3;
is the same as
if(i = 0)
j = 2;
else
j = 3;
Here, i = 0 assigns 0 to i and since 0 is considered as false, the else executes, assigning 3 to j.
Do note that = is the assignment operator and assigns its left and right operands. This is different from the conditional operator == which compares both its operands and returns 0 if false and 1 if true.
If you meant ==, then j=(i==0)?2:3; is the same as
if(i == 0)
j = 2;
else
j = 3;
which will assign 2 to j as i == 0 is true.
To prevent these kind of mistakes, you can use Yoda Conditions as suggested by #JackWhiteIII, i.e , reversing the condition. For example,
j=(i=0)?2:3;
can be written as
j=(0=i)?2:3;
Since 0 is a constant value and cannot be altered, the compiler is emit an error, preventing these kind of mistakes. Note that both 0 == i and i == 0 do the same thing and both are indeed valid.
i=0 is an assignment. Use i==0 for comparison.
Assignments return the new value of the variable that is being assigned to. In your case, that's 0. Evaluated as a condition, that's false.
As in the above code snippet,
{
int i=0;
int j;
j=(i=0)?2:3;
printf("the answer is %d",j);
}
you mistyped, (i==0) with (i=0) which just assigns 0 to i and checks the result, hence you're getting the output as, the answer is 3. The new code would be like,
{
int i=0;
int j;
j=(i==0)?2:3;
printf("the answer is %d",j);
}
The above corrected code snipped gives the output as,
the answer is 2.
Because you mistyped the == operator. You are setting i to the value 0 again and testing this value, which is 0, hence false.
Write this instead:
j = (i == 0) ? 2 : 3;
The result of the assignment operator (= in i=0) is the new value of the object (0). 0 is a false value, thus the 'false' branch of your condition is chosen, which is 3.
Related
I am using a program to detect the boundary of each data type, which is like this:
#include <stdio.h>
#include <stdlib.h>
int main()
{
/*first while loop using a++ dosesn't give us a right answer*/
int a = 0;
while (a++ > 0);
printf("int max first = %d\n", a-1);
/*second while loop using ++a performs well*/
int b = 0;
while (++b > 0);
printf("int max second = %d\n", b-1);
system("pause");
return 0;
}
After I compile this propram and excute it, it returns:
int max first = 0
int max second = 2147483647
So I try to debug it, and I find out that in the first part, after a++ becomes 1, then it just stop autoincrement and jump the while loop,while in second part it runs well, why is this happening?
The pre-increment operator (e.g. ++b) is done first, and the value of the expression is the incremented value.
That is
int b = 0;
while (++b > 0) ...
will increment b first and then check its value using the larger-than comparison. Since in the very first iteration ++b will make b equal to 1 the condition will be 1 > 0 which is true.
Now the post-increment operator does the increment after the old value is used.
So for example a++ will return the old value of a and then do the increment.
So with
int a = 0;
while (a++ > 0) ...
the very first iteration a++ will return 0 which means you have the condition 0 > 0 which is false and the loop will never even iterate once. But the value of a will still be incremented, so afterwards it will be equal to 1 (when the loop have already ended).
This behavior of the pre- and post-operators should be part of any decent book, tutorial or class.
after a++ becomes 1, then it just stop autoincrement and jump the
while loop
This happens because of the post and pre increment operators and the ; in while loop working together.
a will be incremented by 1 after the condition a++ > 0 is evaluated. Thus, the condition fails. The ; at the end of the while statement results in an empty loop and the next print statement will be executed even if the condition on which the while loop is based returns true.
This is exactly what happens in the second while loop - the pre increment operator will increment b before the condition is checked inside while (++b > 0);. The empty while loop keeps on adding one to the value of b until there is an overflow.
At this point, strictly speaking, you have invoked undefined behaviour because the operation has resulted in overflowing a signed integer.
Let me rewrite the main function you wrote - so that it becomes easier to understand.
int main()
{
/*first while loop*/
int a = 0;
while (a > 0){ a = a + 1; }
printf("int max first = %d\n", a-1);
/*second while loop*/
int b = 0;
b = b + 1;
while (b > 0){ b = b + 1; }
printf("int max second = %d\n", b-1);
system("pause");
return 0;
}
Some observations regarding what happened here:
Because at the beginning of the first while loop - the value of a is 0 - which is not greater than 0; the loop gets skipped at the beginning. As a result, the first printf outputs 0.
At the beginning of the second while loop, before evaluating the loop control condition; the loop control variable b gets incremented by 1, resulting the value of b becoming 1; which is greater than 0. For this reason, the second loop is executed.
While executing the second loop, the value of b keeps incrementing by 1 until the value of b overflows. At this point, the program encounters undefined behaviour - and exits the while loop if the program doesn't crash or keeps executing the loop indefinitely (in which case, at some stage the OS will terminate the program; or ask the user to terminate it - as the program will become non-responsive).
You mentioned that you wanted to measure the limit of int values; I hope this reference and this reference will help you in some way.
#include <stdio.h>
int main() {
int i =-1;
if(1< i <10){
printf("1");
} else {
printf("2");
}
}
expected output: 2
present output: 1
In the Boolean expression 1 < i < 10 is evaluated left-to right and 1 < i is either true (1) or false (0); so in the subsequent comparison, both 0 < 10 and 1 < 10 are always true, regardless of the value of i.
It is not therefore possible to obtain the output 2 without changing (possibly correcting?) the condition.
Replace with the following:
if ((i > 1) && (i < 10)) {
Then you can trigger the else block by giving to i a value stricly comprised (please suggest a better word) between 1 and 10.
Due to operators precedence it is not possible to achieve this without changing the condition. (The whole condition reduces to true in every cases.)
I know there is a thread about explanation of ! in C, but I did not understand it fully so here we go. From my understanding number! will return 0 for a non-zero number and 1 for 0. I saw a few code online and to identify if the matrix is an identity matrix people used something along the lines of:
for (i = 0; i < row; i++)
{
for (j = 0; j < column; j++)
{
if (a[i][j] != 1 && a[j][i] != 0)
{
flag = 0;
break;
}
}
}
if (flag == 1 )
printf("It is identity matrix \n");
else
printf("It is not a identity matrix \n");
With user inputted matrix size and values with a being the matrix. My question is how does ! mark help in anyway to identify whether it is an identity matrix or not if all it can do is return an input of 1 and 0s. And would there be any other way to identify an identity matrix without the use of?
! always returns an int (thanks to alk for pointing that out), it stands for Logical NOT in this case and just complements a boolean expression, if a boolean expression evaluates to true, say boolean ex = true then !ex would resolve to false (and finally 0) which is the complement of true.
In case of comparison, == is used to check for equality and != is used to check inequality and both of these result in a boolean value which finally gets evaluated to int.
Your code does not check if the matrix is an identity matrix or not. You do not need ! to find out, either: all you need to do is to check that all matrix elements are zero, except on the main diagonal, when i==j, in which case the element must be 1.
Comparison i == j returns zero or one, so all you need to do is checking that for all values i and j the element a[i][j] is equal to the result of comparison i==j:
int flag = 1;
for (i = 0 ; flag && i < row ; i++) {
for (j = 0; flag && j < column; j++) {
int mainDiagonal = (i==j);
flag = a[i][j] == mainDiagonal;
}
}
if (flag == 1 )
printf("It is identity matrix \n");
else
printf("It is not a identity matrix \n");
Note several changes to the loops: since break lets you break out of only one loop, I changed continuation conditions to check the flag.
!= Checks if the values of two operands are equal or not. If the values are not equal, then the condition becomes true. (A != B) is true if A holds 10 and B holds 20.
The exclamation point in C (and many other languages) stands for the logical NOT sign. i.e.- '!=' is 'NOT EQUAL'.
In C specifically NOT on a non-zero number will return 0, while NOT on 0 will return 1 because numbers can be used as TRUE or FALSE notations as well (0 = FALSE, non-zero = TRUE).
Hope that helps
Other answers have already addressed that != means not equal but there are other things not covered.
First of all: Your code does not check for identity matrix
Just give it a try with this matrix:
int a[2][2] = {{1, 1}, {1, 1}};
Further, I don't think any answer has addressed this part:
And would there be any other way to identify an identity matrix without the use of?
Yes, you can write it without use of !=. And it can be done in many ways. Here is just one example:
flag = 1;
for (i = 0; i < row; i++)
{
for (j = 0; j < column; j++)
{
if (i == j)
{
if (a[i][j] == 1) continue;
}
else
{
if (a[i][j] == 0) continue;
}
flag = 0;
}
}
if (flag == 1 )
printf("It is identity matrix \n");
else
printf("It is not a identity matrix \n");
Not very nice code but it is a way to do it without !=
For a real cool way of checking for identity matrix (without using !=) see the answer from #dasblinkenlight : https://stackoverflow.com/a/42328490/4386427
! and != are two different operators.
! is called NOT Operator. This operator reverses the result of the expression it operates on. For example, if the expression evaluates to a non-zero value, then applying ! Operator to it results into a 0. Vice versa, if the expression evaluates to zero then on applying ! Operator to it makes it 1, a nonzero value. The final result after applying ! operator will 0 or 1 is considered to be false or true respectively.
Whereas != is a relational operator, which is used to check if the two operands, on which the != is applied, are not equal. != is called not equals to operator and used to compare two quantities.
Now on your question
if (a[i][j] != 1 && a[j][i] != 0)
{
flag = 0;
break;
}
In above fragment of code the condition will true if and only if a[i][j] is not equals to 1 and a[j][i] is not equals to 0. If so, code inside if will execute.
Here in the code, if the condition is true it will evaluate to 1 which is true, otherwise 0 which is false. As you said "how does ! mark help in anyway to identify whether it is an identity matrix or not", it is not ! mark it is != mark help to identify if the matrix is identity.
Hope this will help.
I have a code:
while (i = j) {
/* not important */
}
For how long will this while loop work? Is it till the moment when the value of variable j is equal to zero?
For while loop properties, quoting C11, chapter §6.8.5/p4, (emphasis mine)
An iteration statement causes a statement called the loop body to be executed repeatedly
until the controlling expression compares equal to 0. [...]
and considering the assignment inside the loop condition, quoting §6.5.16/p3
[...] An
assignment expression has the value of the left operand after the assignment,111) but is not
an lvalue. [...]
So, every time the loop condition is executed, first the current value of j will be assigned to i and then, the value of i will be taken as the controlling expression value.
In other words, the loop will continue until j becomes 0.
That said, iff you are sure about the assignment part as the loop condition statement, put it into double parenthesis like
while ((i = j)){
Less confusion for the compiler and the next developer/maintainer.
For how long will this while loop work? Is it till the moment when the value of variable j is equal to zero?
A while loop would would work till it's the condition or expression evaluates to be false (i.e, 0).
In your code, YES while loop works till the moment when the value of variable j is equal to 0.
Note : The assignment operator in C returns the value of the variable that was assigned i.e, the value of the expression i = j os equal to j.
In while(i = j) , first i is assigned with value of jand then the expression is evaluated whether true or false.
Why not try a simple program :) :
#include <stdio.h>
int main(void)
{
int i = 0,j =10;
while (i = j)
{
printf("in loop when j = %d\n",j);
j--;
}
printf("exited loop when j = %d",j);
}
output :
in loop when j = 10
in loop when j = 9
in loop when j = 8
in loop when j = 7
in loop when j = 6
in loop when j = 5
in loop when j = 4
in loop when j = 3
in loop when j = 2
in loop when j = 1
exited loop when j = 0
An assignment operation always returns the result of the assignment, so the loop will continue until j == 0, this behavior exists so you can chain many assignment operations together like so:
a = b = c;
This is is the simple program that I was writing in C
#include <stdio.h>
int main(void){
int i, j, k;
i = 2; j = 3;
k = i * j == 6;
printf("%d", k);
}
so I know what this program is actually doing two values for the variable's are given here it does the calculation and then check;s the calculated value to the given condition.
Now here is what I am not getting When the program get executed it return's the value 1 when the given condition is satisfied and 0 if not, and i know that 1 stand's for true and o stand's for false but what i was thinking how doe's it do that i mean there is nothing in the program that tell' it to print 0 or 1 for the condition. Is it default in some C compilers to return that values or am i missing some point.
There is nothing in the program that tells it to print 0 or 1 for the condition.
Yes there is, you print k and you assigned the result of the comparison to k. These are all equivalent (given that i = 2 and j = 3):
k = i * j == 6;
k = (i * j == 6);
k = (6 == 6);
k = 1;
Then you print it:
printf("%d", k); // Prints 1
As you said it yourself, logical expressions in C evaluate either to 0 (false) or to 1 (true). That's exactly what "tells it" to put either 0 or 1 into your k variable, depending on whether the condition is satisfied.
Now, you seem to be talking about what your program "returns". I'm not sure what you mean by "returns" here. The program exit code perhaps? Your main function does not contain any return statements, which means that in C89/90 its return value will be unpredictable, while in C99 it will be guaranteed to return 0. I suspect that you are using a C89/90 compiler that simply returns "garbage" from main, which purely accidentally happens to match the final value of k.
In C, there is no true or false, just 1 and 0, or more precisely 0 and not 0.