5. Other than in a for statement, when is the comma operator used?
The comma operator is commonly used to separate variable declarations, function arguments, and expressions, as well as the elements of a for statement. Look closely at the following program, which shows some of the many ways a comma can be used:
#include <stdio.h>
#include <stdlib.h>
void
main(
void
);
void
main()
{
/* Here, the comma operator is used to separate
three variable declarations. */
int
i, j, k;
/* Notice how you can use the comma operator to perform
multiple initializations on the same line. */
i =
0
, j =
1
, k =
2
;
printf(
“i = %d, j = %d, k = %d\n”
, i, j, k);
/* Here, the comma operator is used to execute three expressions
in one line: assign k to i, increment j, and increment k.
The value that i receives is always the rightmost expression. */
i = (j++, k++);
printf(
“i = %d, j = %d, k = %d\n”
, i, j, k);
/* Here, the while statement uses the comma operator to
assign the value of i as well as test it. */
while
(i = (rand() %
100
), i !=
50
)
printf(
“i is %d, trying again…\n”
, i);
printf(
“\nGuess what? i is 50!\n”
);
}
Notice the line that reads
i = (j++, k++);
This line actually performs three actions at once. These are the three actions, in order:
1. Assigns the value of k to i. This happens because the left value (lvalue) always evaluates to the rightmost argument. In this case, it evaluates to k. Notice that it does not evaluate to k++, because k++ is a postfix incremental expression, and k is not incremented until the assignment of k to i is made. If the expression had read ++k, the value of ++k would be assigned to i because it is a prefix incremental expression, and it is incremented before the assignment is made.
2. Increments j.
3. Increments k.
Also, notice the strange-looking while statement:
while
(i = (rand() %
100
), i !=
50
)
printf(
“i is %d, trying again…\n”
);
Here, the comma operator separates two expressions, each of which is evaluated for each iteration of the whilestatement. The first expression, to the left of the comma, assigns i to a random number from 0 to 99.
The second expression, which is more commonly found in a while statement, is a conditional expression that tests to see whether i is not equal to 50. For each iteration of the while statement, i is assigned a new random number, and the value of i is checked to see that it is not 50. Eventually, i is randomly assigned the value 50, and the while statement terminates.
6. Can the last case of a switch statement skip including the break?
Even though the last case of a switch statement does not require a break statement at the end, you should addbreak statements to all cases of the switch statement, including the last case. You should do so primarily because your program has a strong chance of being maintained by someone other than you who might add cases but neglect to notice that the last case has no break statement.
This oversight would cause what would formerly be the last case statement to “fall through” to the new statements added to the bottom of the switch statement. Putting a break after each case statement would prevent this possible mishap and make your program more “bulletproof.” Besides, most of today’s optimizing compilers will optimize out the last break, so there will be no performance degradation if you add it.
7. How can you tell whether a loop ended prematurely?
Generally, loops are dependent on one or more variables. Your program can check those variables outside the loop to ensure that the loop executed properly. For instance, consider the following example:
#define REQUESTED_BLOCKS 512
int
x;
char
* cp[REQUESTED_BLOCKS];
/* Attempt (in vain, I must add…) to
allocate 512 10KB blocks in memory. */
for
(x=
0
; x< REQUESTED_BLOCKS; x++)
{
cp[x] = (
char
*) malloc(
10000
,
1
);
if
(cp[x] == (
char
*) NULL)
break
;
}
/* If x is less than REQUESTED_BLOCKS,
the loop has ended prematurely. */
if
(x < REQUESTED_BLOCKS)
printf(
“Bummer! My loop ended prematurely!\n”
);
Notice that for the loop to execute successfully, it would have had to iterate through 512 times. Immediately following the loop, this condition is tested to see whether the loop ended prematurely. If the variable x is anything less than 512, some error has occurred.