All integers or pointers can be used in an expression that is interpreted as "truth value".
int main(int argc, char* argv[]) {
if (argc % 4) {
puts("arguments number is not divisible by 4");
} else {
puts("argument number is divisible by 4");
}
...
The expression argc % 4
is evaluated and leads to one of the values 0
, 1
, 2
or 3
. The first, 0
is the only value that is "false" and brings execution into the else
part. All other values are "true" and go into the if
part.
double* A = malloc(n*sizeof *A);
if (!A) {
perror("allocation problems");
exit(EXIT_FAILURE);
}
Here the pointer A
is evaluated and if it is a null pointer, an error is detected and the program exits.
Many people prefer to write something as A == NULL
, instead, but if you have such pointer comparisons as part of other complicated expressions, things become quickly difficult to read.
char const* s = ....; /* some pointer that we receive */
if (s != NULL && s[0] != '\0' && isalpha(s[0])) {
printf("this starts well, %c is alphabetic\n", s[0]);
}
For this to check, you'd have to scan a complicated code in the expression and be sure about operator preference.
char const* s = ....; /* some pointer that we receive */
if (s && s[0] && isalpha(s[0])) {
printf("this starts well, %c is alphabetic\n", s[0]);
}
is relatively easy to capture: if the pointer is valid we check if the first character is non-zero and then check if it is a letter.