Exclamation mark in C array (identity matrix) - c

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.

Related

Without changing condition in if statement i need to print else statement by giving any value to i?

#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 wonder whats happens when if(i%2) what does it checks to come to continue. It misses == but it prints out the sum as 20? Why?

#import <stdio.h>
int main(void) {
int sum,i;
sum = 0;
for(i=0;i<10;i++) {
if(i%2)
continue;
sum+=i;
}
printf("\n%d",sum);
return 0;
}
How does if(i%2) works in the above code?
In computing, the modulo operation finds the remainder after division of one number by another (sometimes called modulus).% is the modulus operator.
So i%2 returns the remainder left after i is divided by 2.
Therefore if i is odd i%2=1(TRUE)
else it is 0(FALSE).(even condition)
Therefore if i is even i is added to sum else the loop continues.
if condition knows only TRUE or FALSE.
If your modulo operation make a true condition then it will execute continue. Otherwise it will do sum.
**True condition = any number without zero(0)
Here, the % used is called the modulo operator. It checks the remainder of a division.
Regarding the if statement, the C11 standard says, from chapter ยง6.8.4.1
Syntax : if ( expression ) statement
and
... the first sub-statement is executed if the expression compares unequal to 0.
So, for a statement like if(i%2), the result
is TRUE, when the i value is not a multiple of 2, i.e., produces a non-zero remainder, so continue; is encountered.
is FALSE, when i is perfectly divisible by 2. so, continue; is skipped and
sum+=i; is executed.
That said, there is no #import <stdio.h> in C, it should be #include <stdio.h>
Finaly,
How does if(i%2) works in the above code?
It is used to add all the even numbers up to 9. The result, 20, is then printed out.
The condition in the if statement
if ( i % 2 )
is equivalent to
if ( i % 2 != 0 )
This condition is equal to true if i is an odd number.
So the program finds the sum of even numbers in the range [0, 10 )
According to the C Standard (6.8.4.1 The if statement)
2 In both forms, the first substatement is executed if the
expression compares unequal to 0.
Here "the first substatement" means the if statement (if else is present then it is the second substatement).
It is better to rewrite the loop without the break statement. For example
for ( i = 0; i < 10; i++ )
{
if ( i % 2 == 0 ) sum += i;
}
It is the same as
for ( i = 0; i < 10; i += 2 )
{
sum += i;
}

Conditional Operator Query in C

{
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.

Condition checking in a for loop

Consider this code:
int main()
{
int i;
int ints[3];
ints[0] = 0;
ints[1] = 1;
ints[2] = 2;
for(i = 0; (ints[i])<4 && i<3; i++)
{
printf("%d\n", ints[i]);
}
}
Is there a reason I shouldn't do this sort of conditioning in the loop? I mean, when i becomes 3, will it look for a non-existing value at ints[3]? And if yes, is it ok?, since the loop is going to terminate anyway? It compiles and runs fine, but I was just wondering if there is some sort of a hidden problem with this. Thanks.
In the last iteration of this loop, the expression ints[i]<4 will access ints[3]. Since this access reads past the end of the array ints, the behavior is undefined in C. So yes, this is not good code. It may work most of the time, but the behavior is ultimately undefined.
It will be better to do i < 3 && ints[i] < 4 because the second part of the statement is evaluated only if the first one is true. The way you have it, it will look for ints[3] that does not exist.
It isn't okay to do this, because ints[3] will indeed be accessed. Now, because this is C, you're not going to get an error (unfortunately), but you'll never know for sure what the outcome would be.
Swapping the statements will solve the problem, because the && operator is optimized so that it doesn't evaluate the second condition if the first one is false.
The 'for' keyword expands out the following way:
int i;
for(i = 0; i < 2; i++)
dothing();
becomes
int i;
i = 0; /* first part of (i = 0; ...) */
beginloop:
if (i >= 2) goto endloop; /* second part of (...; i < 2; ...) */
dothing();
i++; /* final part of (...; ...; i++) */
goto beginloop;
endloop:
So, your code would expand out as follows:
i = 0;
beginloop:
if (ints[i] >= 4)
goto endloop;
if (i >= 3)
goto endloop;
printf(...);
i++;
goto beginloop;
endloop:
While this is fine, there is a problem with the ordering of your tests:
(ints[i] < 4) && (i < 3)
You should always check array indexes first to ensure they are valid before using them:
i = 0:
ints[0] < 4 && 0 < 3
i = 1:
ints[1] < 4 && 1 < 3
i = 2:
ints[2] < 4 && 2 < 3
i = 3:
ints[3] < 4 && 3 < 3 /* illegal access to ints[3] */
As a general rule of thumb, always try to order your conditionals in order of cost unless there is a better reason for the ordering, such as priority: In this case, i < 3 is the cheaper of the two tests, plus it is a constraint on the elements of ints you can access, so you checking the index should have a higher priority - you should check it before using it to tests ints[i] for anything.
The way you have written the loop, your code will try to read the non-existing array element ints [3]. That's undefined behaviour; a consequence is that anything can happen. Right now the whole internet is in uproar because of some code in OpenSSL that invoked undefined behaviour.
The loop terminates, that's okay. But you're accessing an area outside of what you're allowed to. It is undefined behaviour. You may get a segmentation anytime. But you're lucky.
Try putting i<3 before. That would work just fine.
for(i = 0; i<3 && (ints[i])<4; i++)
If i becomes 3, the second part is not evaluated. See short circuit evaluation.

Increasing intervals in an array, check

So I'm trying to check if an array that was previously inputted is increasing in intervals of 1, starting with the number 1 and ending with n (n being the array size).
Here's what I got so far:
for (int i =0; i<n;i++){
for (next=i;next<n;next++){
if(arr[i]+1 = arr[next]){
x = 1; //ignore this, it relates to the rest of the code.
}
else{
printf ("\nThis is not a permutation.");
break;
}
}
}
Now, my thinking is that this code would compare parameters that are next to each other, and if the following parameter is equal to the previous +1, then it is obviously increasing by 1. Problem is, when this is false, it wont print "This is not a permutation," and wont break the loop.
Any help would be appreciated.
Also, any insight as to checking if the array starts with the number 1 would be appreciated.
Thanks
Looks like in this line:
if(arr[i]+1 = arr[next]){
You intended comparison:
if(arr[i]+1 == arr[next]){
Have you tried if(arr[i]+1 == arr[next]) instead of if(arr[i]+1 = arr[next])??
If you need to check that a sequence is increasing, why are you comparing every element against the others? You should only need one for loop:
for (i = 1; i < n; i++)
{
if (arr[i - 1] + 1 == arr[i])
... // keep going
else
... // not a permutation
}
Basically, what your code does is check that every element after the i-th one is greater than that i-th one by one. Ultimately, this leads to an impossible case (as two numbers must be equal but must differ by one at the same time).
It sounds like you want to test if arr[0] == 1 and every subsequent array element is 1 greater than the previous element. Isn't that the same as checking your array for the values [1,2,3,...,n]?
for (int i = 0; i < n; ++n) {
if (arr[i] != i + 1) {
printf("\nThis is not a permutation.");
break;
}
}

Resources