Navigator Bar

Friday, 1 April 2011

More Operators

In Hour 6, "Manipulating Data with Operators," you learned about some important operators in C, such as the arithmetic assignment operators, the unary minus operator, the increment and decrement operators, and the relational operators. In this lesson you'll learn about more operators, including
  • The sizeof operator
  • Logical operators
  • Bit-manipulation operators
  • The conditional operator

Measuring Data Sizes

You may remember in Hour 4, "Data Types and Names in C," I mentioned that each data type has its own size. Depending on the operating system and the C compiler you're using, the size of a data type varies. For example, on most UNIX workstations, an integer is 32 bits long, while most C compilers only support 16-bit integers on a DOS-based machine.
So, how do you know the size of a data type on your machine? The answer is that you can measure the data type size by using the sizeof operator provided by C.
The general form of the sizeof operator is
sizeof (expression)
Here expression is the data type or variable whose size is measured by the sizeof operator. The value of the size is returned, in units of bytes, by the sizeof operator. For instance, if an integer is 16 bits long, the value returned by the sizeof operator will be 2 (bytes). (Note that 8 bits are equal to 1 byte.)
The parentheses are optional in the general form of the operator. If the expression is not a C keyword for a data type, the parentheses can be discarded.
For instance, the following statement
size = sizeof(int);
measures the size of the int data type and returns the number of bytes required by the data type to an int variable size.
The program in Listing 8.1 finds the sizes of the char, int, float, and double data types on my machine.

TYPE
Listing 8.1. Using the sizeof operator.

1:  /* 08L01.c: Using the sizeof operator */
2:  #include <stdio.h>
3:
4:  main()
5:  {
6:     char   ch = ` `;
7:     int    int_num = 0;
8:     float  flt_num = 0.0f;
9:     double dbl_num = 0.0;
10:
11:    printf("The size of char is: %d-byte\n", sizeof(char));
12:      printf("The size of ch is: %d-byte\n", sizeof ch );
13:        printf("The size of int is: %d-byte\n", sizeof(int));
14:          printf("The size of int_num is: %d-byte\n", sizeof int_num);
15:            printf("The size of float is: %d-byte\n", sizeof(float));

16:          printf("The size of flt_num is: %d-byte\n", sizeof flt_num);
17:        printf("The size of double is: %d-byte\n", sizeof(double));
18:      printf("The size of dbl_num is: %d-byte\n", sizeof dbl_num);
19:    return 0;
20: }
OUTPUT
After this program is compiled and linked, an executable file, 08L01.exe, is created. The following is the output printed on the screen after the executable is run from a DOS prompt on my machine:
C:\app> 08L01
The size of char is: 1-byte
The size of ch is: 1-byte
The size of int is: 2-byte
The size of int_num is: 2-byte
The size of float is: 4-byte
The size of flt_num is: 4-byte
The size of double is: 8-byte
The size of dbl_num is: 8-byte
C:\app>
ANALYSIS
Line 2 in Listing 8.1 includes the header file stdio.h for the printf() function used in the statements inside the main() function body. Lines 6_9 declare a char variable (ch), an int variable (int_num), a float variable (flt_num), and a double variable (dbl_num), respectively. Also, these four variables are initialized. Note that in line 8, the initial value to flt_num is suffixed with f to specify float. (As you learned in Hour 4, you can use f or F to specify the float type for a floating-point number.)
Lines 11 and 12 display the size of the char data type, as well as the char variable ch. Note that the sizeof operator is used in both line 11 and line 12 to obtain the number of bytes the char data type or the variable ch can have. Because the variable ch is not a keyword in C, the parentheses are discarded for the sizeof operator in line 12.
The first two lines in the output are printed out by executing the two statements in line 11 and 12, respectively. From the output, you see that the size of the char data type is 1 byte long, which is the same as the size of the variable ch. This is not surprising because the variable ch is declared as the char variable.
Likewise, lines 13 and 14 print out the sizes of the int data type and the int variable int_num by using the sizeof operator. You see that the size of each is 2 bytes.
Also, by using the sizeof operator, lines 15_18 give the sizes of the float data type, the float variable flt_num, the double data type, and the double variable dbl_num, respectively. The results in the output section show that the float data type and the variable flt_num have the same size (4 bytes). The double data type and the variable dbl_num are both 8 bytes long.
From the output you see that char uses 1 byte, while an int uses 2 bytes. Accordingly, while variables of type char have been used to store integers, they cannot store integers of the same range as a variable of type int can.

Everything Is Logical

Now, it's time for you to learn about a new set of operators: logical operators.
There are three logical operators in the C language:
&& The logical AND operator
|| The logical OR operator
! The logical negation operator
The logical AND operator (&&) evaluates the truth or falseness of pairs of expressions. If both expressions are true, the logical AND operator returns 1. Otherwise, the operator returns 0.
However, the logical OR operator (||) returns 1 if at least one of the expressions is true. The || operator returns 0 if both expressions are false.
Only one operand (or expression) can be taken by the logical negation operator (!). If the operand is true, the ! operator returns 0; otherwise, the operator returns 1.


NOTE
In C, if an expression or operator returns a nonzero value, the expression returns TRUE. If an expression or operator returns 0, the expression returns FALSE. In other words, TRUE can be used to represent any nonzero value returned by an expression or operator; FALSE is equivalent to 0.

The following three sections contain examples that show you how to use the three logical operators.

The Logical AND Operator (&&)

A general format of using the logical AND operator is:
exp1 && exp2
where exp1 and exp2 are two expressions evaluated by the AND operator.
We can have a table that shows the return values of the AND operator under the following conditions when exp1 and exp2 return 1 or 0, respectively. See Table 8.1, which can be called the truth table of the AND operator.

Table 8.1. The values returned by the AND operator.

exp1 exp2 Value Returned by &&
1 1 1
1 0 0
0 1 0
0 0 0
Listing 8.2 is an example of using the logical AND operator (&&).

TYPE
Listing 8.2. Using the logical AND operator (&&).

1:  /* 08L02.c: Using the logical AND operator */
2:  #include <stdio.h>
3:
4:  main()
5:  {
6:     int   num;
7:
8:     num = 0;
9:     printf("The AND operator returns: %d\n",
10:           (num%2 == 0) && (num%3 == 0));
11:    num = 2;
12:    printf("The AND operator returns: %d\n",
13:           (num%2 == 0) && (num%3 == 0));
14:    num = 3;
15:    printf("The AND operator returns: %d\n",
16:           (num%2 == 0) && (num%3 == 0));
17:    num = 6;
18:    printf("The AND operator returns: %d\n",
19:           (num%2 == 0) && (num%3 == 0));
20:
21:    return 0;
22: }
OUTPUT
After this program is compiled and linked, an executable file, 08L02.exe, is created. The following is the output printed on the screen after the executable is run from a DOS prompt on my machine:
C:\app> 08L02
The AND operator returns: 1
The AND operator returns: 0
The AND operator returns: 0
The AND operator returns: 1
C:\app>
ANALYSIS
In Listing 8.2, an integer variable, num, is declared in line 6 and initialized for the first time in line 8. Lines 9 and 10 print out the value returned by the logical AND operator in the following expression:
(num%2 == 0) && (num%3 == 0)
Here you see two relational expressions, num%2 == 0 and num%3 == 0. In Hour 3, "The Essentials of C Programs," you learned that the arithmetic operator % can be used to obtain the remainder after its first operand is divided by the second operand. Therefore, num%2 yields the remainder of num divided by 2. The relational expression num%2 == 0 returns 1 (TRUE) if the remainder is equal to 0—that is, the value of num can be divided evenly by 2. Likewise, if the value of num can be divided by 3, the relational expression num%3 == 0 returns 1 as
well. Then, according to the truth table of the && operator (see Table 8.1), we know that the combination of the logical AND operator (&&) and the two relational expressions yields 1 if the two relational expressions both return 1; otherwise, it yields 0.
In our case, when num is initialized to 0 in line 8, both 0%2 and 0%3 yield remainders of 0 so that the two relational expressions return TRUE. Therefore, the logical AND operator returns 1.
However, when num is assigned with the value of 2 or 3 as shown in lines 11 and 14, the logical AND operator in line 13 or line 16 returns 0. The reason is that 2 or 3 cannot be divided by both 2 and 3.
Line 17 then assigns num the value of 6. Because 6 is a multiple of both 2 and 3, the logical
AND operator in line 19 returns 1, which is printed out by the printf() function in lines 18 and 19.
From the program in Listing 8.2, you see several single statements spanning into multiple lines. The output from the program in Listing 8.2 shows the values returned by the AND operator when num is assigned with different values.

The Logical OR Operator (||)

As mentioned earlier, the logical OR operator returns 1 if at least one of the expressions is true. The || operator returns 0 if both expressions are false.
A general format of using the logical OR operator is:
exp1 || exp2
where exp1 and exp2 are two expressions evaluated by the OR operator.

Table 8.2 shows the truth table of the OR operator.

exp1 exp2 Value Returned by ||
1 1 1
1 0 1
0 1 1
0 0 0
The program in Listing 8.3 shows how to use the logical OR operator (||).

TYPE
Listing 8.3. Using the logical OR operator (||).

1:  /* 08L03.c: Using the logical OR operator */
2:  #include <stdio.h>
3:
4:  main()
5:  {
6:     int   num;
7:
8:     printf("Enter a single digit that can be divided\nby both 2 and 3:\n");
9:     for (num = 1; (num%2 != 0) || (num%3 != 0); )
10:       num = getchar() - 48;
11:    printf("You got such a number: %d\n", num);
12:    return 0;
13: }
OUTPUT
The following is the output printed on the screen after the executable, 08L03.exe, is run from a DOS prompt on my machine. The numbers in bold font are what I entered. (The Enter key is pressed after each number is entered.) In the range of 0_9, 0 and 6 are the only two numbers that can be divided evenly by both 2 and 3:
C:\app> 08L03
Enter a single digit that can be divided
by both 2 and 3:
2
3
4
5
6
You got such a number: 6
C:\app>
ANALYSIS
In Listing 8.3, an integer variable, num, is declared in line 6. Line 8 of Listing 8.3 prints out a headline asking the user to enter a single digit. Note that there is a newline character (\n) in the middle of the headline message in the printf() function to break the message into two lines.
In line 9, the integer variable num is initialized in the first expression field of the for statement. The reason to initialize num with 1 is that 1 is such a number that cannot be divided by either 2 nor 3. Thus, the for loop is guaranteed to be executed at least once.
The key part of the program in Listing 8.3 is the logical expression in the for statement:
(num%2 != 0) || (num%3 != 0)
Here the relational expressions num%2 != 0 and num%3 != 0 are evaluated. According to the truth table of the || operator (see Table 8.2), we know that if one of the relational expression returns TRUE, i.e., the value of num cannot be divided completely by either 2 or 3. Then the logical expression returns 1, which allows the for loop to continue.
The for loop stops only if the user enters a digit that can be divided by both 2 and 3. In other words, when both the relational expressions return FALSE, the logical OR operator yields 0, which causes the termination of the for loop.
You can rewrite the program in Listing 8.3 with the if statement, too.

The Logical Negation Operator (!)

A general format of using the logical OR operator is:
!expression
where expression is an expression operated by the negation operator.
The truth table of the negation operator is shown in Table 8.3.

Table 8.3. The values returned by the ! operator.

expression Value Returned by !
1 0
0 1
TYPE
Now, let's take a look at the example, shown in Listing 8.4, that demonstrates how to use the logical negation operator (!).

Listing 8.4. Using the logical negation operator (!).

1:  /* 08L04.c: Using the logical negation operator */
2:  #include <stdio.h>
3:
4:  main()
5:  {
6:     int   num;
7:
8:     num = 7;
9:     printf("Given num = 7\n");
10:    printf("!(num < 7)  returns: %d\n", !(num < 7));
11:    printf("!(num > 7)  returns: %d\n", !(num > 7));
12:    printf("!(num == 7) returns: %d\n", !(num == 7));
13:    return 0;
14: }
OUTPUT
The following result is obtained by running the executable file 08L04.exe:
C:\app> 08L04
Given num = 7
!(num < 7)  returns: 1
!(num > 7)  returns: 1
!(num == 7) returns: 0
C:\app>
ANALYSIS
In line 8, note that an integer variable, num, is initialized with 7, which is then displayed by the printf() function in line 9.
In line 10, the relational expression num < 7 returns FALSE (that is, 0), because the value of num is not less than 7. However, by using the logical negation operator, !(num < 7) yields 1. (Refer to the truth table of the ! operator shown in Table 8.3.)
Similarly, the logical expression !(num > 7) returns 1 in line 11.
Because num has the value of 7, the relational expression num == 7 is true; however, the
logical expression !(num == 7) in line 12 returns 0 due to the logical negation operator (!).

Manipulating Bits

In previous hours, you learned that computer data and files are made of bits (or bytes). There is even an operator in C_the sizeof operator_that can be used to measure the number of bytes for data types.
In this section, you'll learn about a set of operators that enable you to access and manipulate specific bits.
There are six bit-manipulation operators in the C language:
Operator Description
& The bitwise AND operator
| The bitwise OR operator
^ The bitwise exclusive OR (XOR) operator
~ The bitwise complement operator
>> The right-shift operator
<< The left-shift operator
The following two sections give explanations and examples of the bit-manipulation
operators.


TIP
It's easy to convert a decimal number into a hex or a binary. Each digit in a hex number consists of four bits. A bit represents a digit in a binary number. Table 8.4 shows the hex numbers (0_F) and their corresponding binary and decimal representations.

 

Table 8.4. Numbers expressed in different formats.

Hex Binary Decimal
0 0000 0
1 0001 1
2 0010 2
3 0011 3
4 0100 4
5 0101 5
6 0110 6
7 0111 7
8 1000 8
9 1001 9
A 1010 10
B 1011 11
C 1100 12
D 1101 13
E 1110 14
F 1111 15
Let's see how to convert a decimal number into a binary, or vice versa. As we know, that binary is a 2-based numbering system. Each digit in a binary number is called a bit and can be 1 or 0. If the position of a bit in a binary number is n, then the bit can have a value of 2 to the power of n. The position of a bit in a binary number is counted from the right of the binary number. The most-right bit is at the position of zero. Thus, given a binary number 1000, we can calculate its decimal value like this:
1000 -> 1 * 23 + 0 *22 + 0 * 21 + 0 * 20-> 23 -> 8 (decimal)
That is, the decimal vale of the binary number 1000 is 8.
If we want to convert a decimal number, for example 10, to its binary counterpart, we have the following process:
10 -> 23 + 21 -> 1 *23 + 0 * 22 + 1 *21 + 0 * 20 -> 1010 (binary)
Likewise, you can convert the rest of the decimal numbers in Table 8.4 to their binary counterparts, or vice versa.

Using Bitwise Operators

The general forms of the bitwise operators are as follows:
x & y
x | y
x ^ y
~x
Here x and y are operands.
The & operator compares each bit of x to the corresponding bit in y. If both bits are 1, 1 is placed at the same position of the bit in the result. If one of the bits, or two of them, is 0, 0 is placed in the result.
For instance, the expression with two binary operands, 01 & 11, returns 01.
The | operator, however, places 1 in the result if either operand is 1. For example, the expression 01 | 11 returns 11.
The ^ operator places 1 in the result if either operand, but not both, is 1. Therefore, the expression 01 ^ 11 returns 10.
Finally, the ~ operator takes just one operand. This operator reverses each bit in the operand. For instance, ~01 returns 10.
Table 8.5 shows more examples of using the bitwise operators in decimal, hex, and binary formats (in the left three columns). The corresponding results, in binary, hex, and decimal formats, are listed in the right three columns. The hex numbers are prefixed with 0x.

Table 8.5. Examples of using bitwise operators.

Decimal Results
Expressions Hex Binary Decimal Hex Binary
12 & 10 0x0C & 0x0A 1100 &1010 8 0x08 1000
12 | 10 0x0C | 0x0A 1100 | 1010 14 0x0E 1110
12 ^ 10 0x0C ^ 0x0A 1100 ^ 1010 6 0x06 0110
~12 ~0x000C ~0000000000001100 65523 FFF3 1111111111110011
TYPE
Note that the complementary value of 12 is 65523, because the unsigned integer data type (16-bit) has the maximum number 65535. In other words, 65,523 is the result of subtracting 12 from 65,535. (The unsigned data modifier is introduced in Hour 9, "Playing with Data Modifiers and Math Functions.")
The program in Listing 8.5 demonstrates the usage of the bitwise operators.

Listing 8.5. Using bitwise operators.

1:  /* 08L05.c: Using bitwise operators */
2:  #include <stdio.h>
3:
4:  main()
5:  {
6:     int   x, y, z;
7:
8:     x = 4321;
9:     y = 5678;
10:    printf("Given x = %u, i.e., 0X%04X\n", x, x);
11:    printf("      y = %u, i.e., 0X%04X\n", y, y);
12:    z = x & y;
13:    printf("x & y  returns: %6u, i.e., 0X%04X\n", z, z);
14:    z = x | y;
15:    printf("x | y  returns: %6u, i.e., 0X%04X\n", z, z);
16:    z = x ^ y;
17:    printf("x ^ y  returns: %6u, i.e., 0X%04X\n", z, z);
18:    printf("  ~x   returns: %6u, i.e., 0X%04X\n", ~x, ~x);
19:    return 0;
20: }
OUTPUT
After the executable, 08L05.exe, is created and run from a DOS prompt, the following output is shown on the screen:
C:\app> 08L05
Given x = 4321, i.e., 0X10E1
      y = 5678, i.e., 0X162E
x & y  returns:  4128, i.e., 0X1020
x | y  returns:  5871, i.e., 0X16EF
     x ^ y  returns:  1743, i.e., 0X06CF
       ~x   returns: 61214, i.e., 0XEF1E
     C:\app>
ANALYSIS
In Listing 8.5, three integer variables, x, y, and z, are declared in line 6. Lines 8 and 9 set x and y to 4321 and 5678, respectively. Lines 10 and 11 then print out the values of x and y in both decimal and hex formats. The hex numbers are prefixed with 0X.
The statement in line 12 assigns the result of the operation made by the bitwise AND operator (&) with the variables x and y. Then, line 13 displays the result in both decimal and hex formats.
Lines 14 and 15 perform the operation specified by the bitwise operator (|) and print out the result in both decimal and hex formats. Similarly, lines 16 and 17 give the result of the operation made by the bitwise XOR operator (^).
Last, the statement in line 18 prints out the complementary value of x by using the bitwise complement operator (~). The result is displayed on the screen in both decimal and hex formats.
Note that the unsigned integer format specifier with a minimum field width of 6, %6u, and the uppercase hex format specifier with the minimum width of 4, %04X, are used in the printf() function. The unsigned integer data type (that is, the non-negative integer data type) is chosen so that the complementary value of an integer can be shown and understood easily. More details on the unsigned data modifier are introduced in Hour 9.


WARNING
Don't confuse the bitwise operators & and | with the logical operators && and ||. For instance,
(x=1) & (y=10)
(x=1) && (y=10)

Using Shift Operators

There are two shift operators in C. The >> operator shifts the bits of an operand to the right; the << operator shifts the bits to the left.
The general forms of the two shift operators are
x >> y
x << y
Here x is an operand that is going to be shifted. y contains the specified number of places to shift.
For instance, the 8 >> 2 expression tells the computer to shift 2 bits of the operand 8 to the right, which returns 2 in decimal. The following:
8 >> 2 -> (1 * 23 + 0 *22 + 0 * 21 + 0 *20) >> 2
produces the following:
(0 * 23 + 0 * 22 + 1 *21 + 0 * 20) -> 0010 (binary) -> 2 (decimal).
Likewise, the 5 << 1 expression shifts 1 bit of the operand 5, and yields 10 in decimal.
The program in Listing 8.6 prints out more results by using the shift operators.

TYPE
Listing 8.6. Using the shift operators.

1:  /* 08L06.c: Using shift operators */
2:  #include <stdio.h>
3:
4:  main()
5:  {
6:     int   x, y, z;
7:
8:     x = 255;
9:     y = 5;
10:    printf("Given x = %4d, i.e., 0X%04X\n", x, x);
11:    printf("      y = %4d, i.e., 0X%04X\n", y, y);
12:    z = x >> y;
13:    printf("x >> y  returns: %6d, i.e., 0X%04X\n", z, z);
14:    z = x << y;
15:    printf("x << y  returns: %6d, i.e., 0X%04X\n", z, z);
16:    return 0;
17: }
OUTPUT
The following output is obtained by running the executable, 08L06.exe, from a DOS prompt:
C:\app> 08L06
Given x =  255, i.e., 0X00FF
      y =    5, i.e., 0X0005
x >> y  returns:      7, i.e., 0X0007
x << y  returns:   8160, i.e., 0X1FE0
C:\app>
ANALYSIS
Three integer variables, x, y, and z, are declared in line 6 of Listing 8.6. x is initial-ized with
255 in line 8; y is set to 5 in line 9. Then, lines 10 and 11 display the values of x and y on the screen.
The statement in line 12 shifts y bits of the operand x to the right, and then assigns the result to z. Line 13 prints out the result of the shifting made in line 12. The result is 7 in decimal, or 0X0007 in hex.
Lines 14 and 15 shift the operand x to the left by y bits and display the result on the screen, too. The result of the left-shifting is 8160 in decimal, or 0x1FE0 in hex.


TIP
The operation of the shift-right operator (>>) is equivalent to dividing by powers of 2. In other words, the following:
x >> y
x / 2y
Here x is a non-negative integer.
On the other hand, shifting to the left is equivalent to multiplying by powers of 2; that is,
x << y
x * 2y

What Does x?y:z Mean?

In C, ?: is called the conditional operator, which is the only operator that takes three operands. The general form of the conditional operator is
x ? y : z
Here x, y, and z are three operands. Among them, x contains the test condition, and y and z represent the final value of the expression. If x returns nonzero (that is, TRUE), y is chosen; otherwise, z is the result.
For instance, the expression x > 0 ? `T' : `F' returns `T' if the value of x is greater than 0. Otherwise, the expression returns `F'.
Listing 8.7 demonstrates the usage of the conditional operator in the C language.

TYPE
Listing 8.7. Using the conditional operator.

1:  /* 08L07.c: Using the ?: operator */
2:  #include <stdio.h>
3:
4:  main()
5:  {
6:     int   x;
7:
8:     x = sizeof(int);
9:     printf("%s\n",
10:       (x == 2) ? "The int data type has 2 bytes." : "int doesn't have 2
                      Âbytes.");
11:    printf("The maximum value of int is: %d\n",
12:       (x != 2) ? ~(1 << x * 8 - 1) : ~(1 << 15) );
13:    return 0;
14: }
OUTPUT
I get the following output shown on the screen when I run the executable 08L07.exe from a DOS prompt on my machine:
C:\app> 08L07
The int data type has 2 bytes.
The maximum value of int is: 32767
C:\app>
ANALYSIS
In Listing 8.7, the size of the int data type is measured first in line 8, by using the sizeof operator and the number of bytes assigned to the integer variable x.
Lines 9 and 10 contain one statement, in which the conditional operator (?:) is used to test whether the number of bytes saved in x is equal to 2. (Here you see another example that a single statement can span multiple lines.) If the x == 2 expression returns nonzero (that is, TRUE), the string of The int data type has 2 bytes. is printed out by the printf() function in the statement. Otherwise, the second string, int doesn't have 2 bytes., is displayed on the screen.
In addition, the statement in lines 11 and 12 tries to find out the maximum value of the int data type on the current machine. The x != 2 expression is evaluated first in the statement. If the expression returns nonzero (that is, the byte number of the int data type is not equal to 2), the ~( << x * 8 - 1) expression is evaluated, and the result is chosen as the return
value. Here the ~(1 << x * 8 - 1) expression is a general form to calculate the maximum value of the int data type, which is equivalent to 2 ** (x * 8 - 1) - 1. (The complement operator, ~, and the shift operator, <<, were introduced in the previous sections of this hour.)
On the other hand, if the test condition x != 2 in line 12 returns 0, which means the value of x is indeed equal to 2, the result of the ~(1 << 15) expression is chosen. Here you may have already figured out that ~(1 << 15) is equivalent to 215_1, which is the maximum value that the 16-bit int data type can have.
The result displayed on the screen shows that the int data type on my machine is 2 bytes
(or 16 bits) long, and the maximum value of the int data type is 32767.


SOURCE LINK Read More..

Doing the Same Thing Over and Over

In the previous lessons, you've learned the basics of the C program, several important C functions, standard I/O, and some useful operators. In this lesson you'll learn a very important feature of the C language—looping. Looping, also called iteration, is used in programming to perform the same set of statements over and over until certain specified conditions are met.
Three statements in C are designed for looping:
  • The for statement
  • The while statement
  • The do-while statement
The following sections explore these statements.


Looping Under the for Statement

The general form of the for statement is
for (expression1; expression2; expression3) {
   statement1;
   statement2;
   .
   .
   .
}
You see from this example that the for statement uses three expressions (expression1, expression2, and expression3) that are separated by semicolons.
Several statements, such as statement1 and statement2, are placed within the braces ({ and }). All the statements and the braces form a statement block that is treated as a single statement. (You learned about this in Hour 3, "The Essentials of C Programs.")
In the preceding for statement format, the beginning brace ({) is put on the same line of the for keyword. You can place the beginning brace on a separate line beneath the for keyword.
The for statement first evaluates expression1, which usually initializes one or more variables. In other words, expression1 is only evaluated once when the for statement is first encountered.
The second expression, expression2, is the conditional part that is evaluated right after the evaluation of expression1 and then is evaluated after each successful looping by the for statement. If expression2 returns a nonzero value, the statements within the braces are executed. Usually, the nonzero value is 1. If expression2 returns 0, the looping is stopped and the execution of the for statement is finished.
The third expression in the for statement, expression3, is not evaluated when the for statement is first encountered. However, expression3 is evaluated after each looping and before the statement goes back to test expression2 again.
In Hour 5, "Reading from and Writing to Standard I/O," you saw an example (in Listing 5.5) that converts the decimal numbers 0 through 15 into hex numbers. Back then, conversions made for each number had to be written in a separate statement. Now, with the for statement, we can rewrite the program in Listing 5.5 in a very efficient way. Listing 7.1 shows the rewritten version of the program.

TYPE
Listing 7.1. Converting 0 through 15 to hex numbers.

1:  /* 07L01.c: Converting 0 through 15 to hex numbers */
2:  #include <stdio.h>
3:
4:  main()
5:  {
6:     int i;
7:
8:     printf("Hex(uppercase)   Hex(lowercase)   Decimal\n");
9:     for (i=0; i<16; i++){
10:       printf("%X                %x                %d\n", i, i, i);
11:    }
12:    return 0;
13: }
OUTPUT
After creating the executable file 07L01.exe and running it by typing in 07L01 from a DOS prompt, I obtain the same output as the one from 05L05.exe:
C:\app> 07L01
Hex(uppercase)   Hex(lowercase)   Decimal
0                0                0
1                1                1
2                2                2
3                3                3
4                4                4
5                5                5
6                6                6
7                7                7
8                8                8
9                9                9
A                a                10
B                b                11
C                c                12
D                d                13
E                e                14
F                f                15
C:\app>
ANALYSIS
Now, let's have a look at the code in Listing 7.1. As you know, line 2 includes the header file stdio.h for the printf() function used later in the program.
Inside the body of the main() function, the statement in line 6 declares an integer variable, i. Line 8 displays the headline of the output on the screen.
Lines 9_11 contain the for statement. Note that the first expression in the for statement is i=0, which is an assignment expression that initializes the integer variable i to 0.
The second expression in the for statement is i<16, which is a relational expression. This expression returns 1 as long as the relation indicated by the less-than operator (<) holds. As mentioned earlier, the second expression is evaluated by the for statement each time after a successful looping. If the value of i is less than 16, which means the relational expression remains true, the for statement will start another loop. Otherwise, it will stop looping and exit.
The third expression in the for statement is i++ in this case. This expression is evaluated and the integer variable i is increased by 1 each time after the statement inside the body of the for statement is executed. Here it doesn't make a big difference whether the post-increment operator (i++) or the pre-increment operator (++i) is used in the third expression.
In other words, when the for loop is first encountered, i is set to 0, the expression
i<16
is evaluated and found to be true, and therefore the statements within the body of the for loop are executed. Following execution of the for loop, the third expression i++ is executed incrementing i to 1, and i<16 is again evaluated and found to be true, thus the body of the loop is executed again. The looping lasts until the conditional expression i<16 is no longer true.
There is only one statement inside the for statement body, as you can see in line 10. The statement contains the printf() function, which is used to display the hex numbers (both uppercase and lowercase) converted from the decimal values by using the format specifiers, %X and %x.
Here the decimal value is provided by the integer variable i. As explained, i contains the initial value of 0 right before and during the first looping. After each looping, i is increased by 1 because of the third expression, i++, in the for statement. The last value provided by i is 15. When i reaches 16, the relation indicated by the second expression, i<16, is no longer true. Therefore, the looping is stopped and the execution of the for statement is completed.
Then, the statement in line 12 returns 0 to indicate a normal termination of the program, and finally, the main() function ends and returns the control back to the operating system.
As you see, with the for statement, you can write a very concise program. In fact, the program in Listing 7.1 is more than 10 lines shorter than the one in Listing 5.5, although the two programs can do exactly the same thing.
Actually, you can make the program in Listing 7.1 even shorter. In the for statement, you can discard the braces ({ and }) if there is only one statement inside the statement block.

The Null Statement

As you may notice, the for statement does not end with a semicolon. The for statement has within it either a statement block that ends with the closing brace (}) or a single statement that ends with a semicolon. The following for statement contains a single statement:
for (i=0; i<8; i++)
      sum += i;
Now consider a statement such as this:
for (i=0; i<8; i++);
Here the for statement is followed by a semicolon immediately.
In the C language, there is a special statement called the null statement. A null statement contains nothing but a semicolon. In other words, a null statement is a statement with no expression.
Therefore, when you review the statement for (i=0; i<8; i++);, you can see that it is actually a for statement with a null statement. In other words, you can rewrite it as
for (i=0; i<8; i++)
   ;
Because the null statement has no expression, the for statement actually does nothing but loop. You'll see some examples of using the null statement with the for statement later in the book.


WARNING
Because the null statement is perfectly legal in C, you should pay attention to placing semicolons in your for statements. For example, suppose you intended to write a for loop like this:
for (i=0; i<8; i++)
   sum += i;
for (i=0; i<8; i++);
   sum += i;
your C compiler will still accept it, but the results from the two for statements will be quite different. (See exercise 1 in this lesson for an example.)

Adding More Expressions into for

The C language allows you to put more expressions into the three expression fields in the for statement. Expressions in a single expression field are separated by commas.
For instance, the following form is valid in C:
for (i=0, j=10; i<10, j>0; i++, j--){
   /* statement block */
}
Here, in the first expression field, the two integer variables, i and j, are initialized, respectively, with 0 and 10 when the for statement is first encountered. Then, in the second field, the two relational expressions, i<10 and j>0, are evaluated and tested. If one of the relational expressions returns 0, the looping is stopped. After each iteration and the statements in the statement block are executed successfully, i is increased by 1, j is reduced by 1 in the third expression field, and the expressions i<10 and j>0 are evaluated to determine whether to do one more looping.
Now, let's look at a real program. Listing 7.2 shows an example of using multiple expressions in the for statement.

TYPE
Listing 7.2. Adding multiple expressions to the for statement.

1:  /* 07L02.c: Multiple expressions */
2:  #include <stdio.h>
3:
4:  main()
5:  {
6:     int i, j; 
7:
8:     for (i=0, j=8; i<8; i++, j--)
9:        printf("%d  +  %d  =  %d\n", i, j, i+j);
10:    return 0;
11: }
OUTPUT
I get the following output displayed on the screen after running the executable, 07L02.exe:
C:\app> 07L02
0  +  8  =  8
1  +  7  =  8
2  +  6  =  8
3  +  5  =  8
4  +  4  =  8
5  +  3  =  8
6  +  2  =  8
7  +  1  =  8
C:\app>
ANALYSIS
In Listing 7.2, line 6 declares two integer variables, i and j, which are used in a for loop.
In line 8, i is initialized with 0 and j is set to 8 in the first expression field of the for statement. The second expression field contains a condition, i<8, which tells the computer to keep looping as long as the value of i is less than 8.
Each time, after the statement controlled by for in line 8 is executed, the third expression field is evaluated, and i is increased by 1 while j is reduced by 1. Because there is only one statement inside the for loop, no braces ({ and }) are used to form a statement block.
The statement in line 9 displays the addition of i and j on the screen during the looping, which outputs eight results during the looping by adding the values of the two variables, i and j.
Adding multiple expressions into the for statement is a very convenient way to manipulate more than one variable in a loop. To learn more about using multiple expressions in a for loop, look at the example in Listing 7.3.

TYPE
Listing 7.3. Another example of using multiple expressions in the for statement.

1:  /* 07L03.c: Another example of multiple expressions */
2:  #include <stdio.h>
3:
4:  main()
5:  {
6:     int i, j;
7:
8:     for (i=0, j=1; i<8; i++, j++)
9:        printf("%d  -  %d  =  %d\n", j, i, j - i);
10:    return 0;
11: }
The following output is displayed on the screen after the executable 07L03.exe is run on my machine:
C:\app> 07L03
1  -  0  =  1
2  -  1  =  1
3  -  2  =  1
4  -  3  =  1
5  -  4  =  1
6  -  5  =  1
7  -  6  =  1
8  -  7  =  1
C:\app>
OUTPUT
In Listing 7.3, two integer variables, i and j, are declared in line 6.
ANALYSIS
Note that in line 8, there are two assignment expressions, i=0 and j=1, in the first expression field of the for statement. These two assignment expressions initialize the i and j integer variables, respectively.
There is one relational expression, i<8, in the second field, which is the condition that has to be met before the looping can be carried out. Because i starts at 0 and is incremented by 1 after each loop, there are a total of eight loops that will be performed by the for statement.
The third expression field contains two expressions, i++ and j++, that increase the two integer variables by 1 each time after the statement in line 9 is executed.
The printf() function in line 9 displays the subtraction of the two integer variables, j and i, within the for loop. Because there is only one statement in the statement block, the braces ({ and }) are discarded.

Playing with an Infinite Loop

If you have a for statement like this,
for ( ; ; ){
  /* statement block */
}
you encounter an infinite loop. Note that in this for statement, there are no expressions in the three expression fields. The statements inside the statement block will be executed over and over without stopping.
You use the infinite loop if you don't know the exact number of loops you need. However, you have to set up some other conditions with the loop to test and determine whether and when you want to break the infinite loop.
The program in Listing 7.4 demonstrates an example that takes the characters entered by the user, and puts them on the screen. The for loop in the program keeps looping until the user enters the character x.

TYPE
Listing 7.4. Adding conditions to a for loop.

1:  /* 07L04.c: Conditional loop */
2:  #include <stdio.h>
3:
4:  main()
5:  {
6:     int c;
7:
8:     printf("Enter a character:\n(enter x to exit)\n");
9:     for ( c=' `; c != `x'; ) {
10:       c = getc(stdin);

11:       putchar(c);
12:    }
13:    printf("\nOut of the for loop. Bye!\n");
14:    return 0;
15: }
OUTPUT
After running the executable, 07L04.exe, I enter characters, such as H, i, and the \n character (I have to press the Enter key each time after I enter a character), which are all displayed back on the screen. Finally, I enter x to exit from the infinite for loop. (Note that in the following copy from the screen, the characters that I entered are in bold.)
C:\app> 07L04
Enter a character:
(enter x to exit)
H
H
i
i
x
x
Out of the for loop. Bye!
C:\app>
ANALYSIS
In Listing 7.4, there is only one integer variable, c, declared in line 6. The printf() function in line 8 displays the message Enter a character: on one line on the screen, and another message, (enter x to exit), on another line because there is a newline character (\n) added in the middle of the format string in the printf() function.
In line 9, the integer variable c is initialized with the numeric value of the space character. Then, a condition is evaluated in the second expression field of the for statement like this: c != `x', which means that the condition is met if c does not contain the numeric value of x; otherwise, the condition is not met.
If the condition is met, the two statements in lines 10 and 11 will be executed over and over. The looping can last forever until the user enters the character x. Then, the statement in line 13 prints out a good-bye message right after the looping is terminated.

The while Loop

The while statement is also used for looping. Unlike the situation with the for statement, there is only one expression field in the while statement.
The general form of the while statement is

while (expression) {
   statement1;
   statement2;
   .
   .
   .
}
Here expression is the field of the expression in the while statement. The expression is evaluated first. If the expression returns a nonzero value (normally 1), the looping continues; that is, the statements inside the statement block are executed. After the execution, the expression is evaluated again. The statements are then executed one more time if the expression still returns nonzero value. The process is repeated over and over until the expression returns 0.
You see that a statement block, surround by the braces { and }, follows the while keyword and the expression field. Of course, if there is only one statement in the statement block, the braces can be discarded.
Now, let's look at an example of using the while statement. The program in Listing 7.5 is a modified version of the one in Listing 7.4, but this one uses the while statement.

TYPE
Listing 7.5. Using a while loop.

1:  /* 07L05.c: Using a while loop */
2:  #include <stdio.h>
3:
4:  main()
5:  {
6:     int c;
7:
8:     c = ` `;
9:     printf("Enter a character:\n(enter x to exit)\n");
10:    while (c != `x') {
11:       c = getc(stdin);
12:       putchar(c);
13:    }
14:    printf("\nOut of the while loop. Bye!\n");
15:    return 0;
16: }
OUTPUT
The executable 07L05.exe can do a similar job as the executable 07L04.exe. The following is a copy from the screen:
C:\app> 07L05
Enter a character:

(enter x to exit)
H
H
i
i
x
x
Out of the while loop. Bye!
C:\app>
ANALYSIS
You see that the output from the execution of the program in Listing 7.5 is similar to the one from Listing 7.4, except the while statement is used in lines 10_13 of Listing 7.5.
The char variable c is initialized with a space character in line 8. Unlike the for statement in Listing 7.4, the while statement does not set c before the looping.
In line 10, the relational expression c != `x' is tested. If the expression returns 1, which means the relation still holds, the statements in lines 11 and 12 are executed. The looping continues as long as the expression returns 1. If, however, the user enters the character x, which makes the relational expression return 0, the looping stops.

The Infinite while Loop

You can also make a while loop infinite by putting 1 in the expression field, like this:
while (1) {
   statement1;
   statement2;
   .
   .
   .
}
Because the expression always returns 1, the statements inside the statement block will be executed over and over—that is, the while loop will continue forever. Of course, you can set certain conditions inside the while loop to break the infinite loop as soon as the conditions are met.
The C language provides some statements, such as if and break statements, that you can use to set conditions and break the infinite while loop if needed. Details on the if and break statements are covered in Hour 10, "Getting Controls."

The do-while Loop

You may note that in the for and while statements, the expressions are set at the top of the loop. However, in this section, you're going to see another statement used for looping,
do-while, which puts the expressions at the bottom of the loop. In this way, the statements controlled by the do-while statement are executed at least once before the expression is tested. Note that statements in a for or while loop are not executed at all if the condition expression does not hold in the for or while statement.
The general form for the do-while statement is
do {
   statement1;
   statement2;
   .
   .
   .
} while (expression);
Here expression is the field for the expression that is evaluated in order to determine whether the statements inside the statement block are to be executed one more time. If the expression returns a nonzero value, the do-while loop continues; otherwise, the looping stops.
Note that the do-while statement ends with a semicolon, which is an important distinction from the if and while statements.
The program in Listing 7.6 displays the characters A through G by using a do-while loop to repeat the printing and adding.

TYPE
Listing 7.6. Using a do-while loop.

1:  /* 07L06.c: Using a do-while loop */
2:  #include <stdio.h>
3:
4:  main()
5:  {
6:     int i;
7:
8:     i = 65;
9:     do {
10:       printf("The numeric value of %c is %d.\n", i, i);
11:       i++;
12:    } while (i<72);
13:    return 0;
14: }
OUTPUT
After running the executable 07L06.exe of Listing 7.6, I have the characters A through G, along with their numeric values, shown on the screen as follows:
C:\app> 07L06
The numeric value of A is 65.
The numeric value of B is 66.
The numeric value of C is 67.
The numeric value of D is 68.
The numeric value of E is 69.
The numeric value of F is 70.
The numeric value of G is 71.
C:\app>
ANALYSIS
The statement in line 8 of Listing 7.6 initializes the integer variable i with 65. The integer variable is declared in line 6.
Lines 9_12 contain the do-while loop. The expression i<72 is at the bottom of the loop in line 12. When the loop first starts, the two statements in lines 10 and 11 are executed before the expression is evaluated. Because the integer variable i contains the initial value of 65, the printf() function in line 10 displays the numeric value as well as the corresponding character A on the screen.
After the integer variable i is increased by 1 in line 11, the program control reaches the bottom of the do-while loop. Then the expression i<72 is evaluated. If the relationship in the expression still holds, the program control jumps up to the top of the do-while loop, and then the process is repeated. When the expression returns 0 after i is increased to 72, the do-while loop is terminated immediately.

Using Nested Loops

You can put a loop inside another one to make nested loops. The computer will run the inner loop first before it resumes the looping for the outer loop.
Listing 7.7 is an example of how nested loops work.

TYPE
Listing 7.7. Using nested loops.

1:  /* 07L07.c: Demonstrating nested loops */
2:  #include <stdio.h>
3:
4:  main()
5:  {
6:     int i, j;
7:
8:     for (i=1; i<=3; i++) {   /* outer loop */

9:        printf("The start of iteration %d of the outer loop.\n", i);
10:       for (j=1; j<=4; j++)  /* inner loop */
11:          printf("    Iteration %d of the inner loop.\n", j);
12:       printf("The end of iteration %d of the outer loop.\n", i);
13:    }
14:    return 0;
15: }
OUTPUT
The following result is obtained by running the executable file 07L07.exe:
C:\app> 07L07
The start of iteration 1 of the outer loop.
    Iteration 1 of the inner loop.
    Iteration 2 of the inner loop.
    Iteration 3 of the inner loop.
    Iteration 4 of the inner loop.
The end of iteration 1 of the outer loop.
The start of iteration 2 of the outer loop.
    Iteration 1 of the inner loop.
    Iteration 2 of the inner loop.
    Iteration 3 of the inner loop.
    Iteration 4 of the inner loop.
The end of iteration 2 of the outer loop.
The start of iteration 3 of the outer loop.
    Iteration 1 of the inner loop.
    Iteration 2 of the inner loop.
    Iteration 3 of the inner loop.
    Iteration 4 of the inner loop.
The end of iteration 3 of the outer loop.
C:\app>
ANALYSIS
In Listing 7.7, two for loops are nested together. The outer for loop starts in line 8 and ends in line 13, while the inner for loop starts in line 10 and ends in line 11.
The inner loop controls one statement that prints out the iteration number according to the numeric value of the integer variable j. As you see in line 10, j is initialized with 1, and is increased by 1 after each looping (that is, iteration). The execution of the inner loop stops when the value of j is greater than 4.
Besides the inner loop, the outer loop has two statements in lines 9 and 12, respectively. The printf() function in line 9 displays a message showing the beginning of an iteration from the outer loop. An ending message is sent out in line 12 to show the end of the iteration from the outer loop.
From the output, you can see that the inner loop is finished before the outer loop starts another iteration. When the outer loop begins another iteration, the inner loop is encountered and run again. The output from the program in Listing 7.7 clearly shows the execution orders of the inner and outer loops.

WARNING
Don't confuse the two relational operators (< and <=) and misuse them in the expressions of loops.
For instance, the following
for (j=1; j<10; j++){
    /* statement block */
}
for (j=1; j<=10; j++){
    /* statement block */
}
the total number of iterations is 10 because the relational expression j<=10 is evaluated in this case. Note that the expression returns 1 as long as j is less than or equal to 10.
Therefore, you see the difference between the operators < and <= causes the looping in the first example to be one iteration shorter than the looping in the second example.


SOURCE LINK
Read More..

Manipulating Data with Operators

You can think of operators as verbs in C that let you manipulate data. In fact, you've learned some operators, such as + (addition), - (subtraction), * (multiplication), / (division), and % (remainder), in  "The Essentials of C Programs." The C language has a rich set of operators. In this hour, you'll learn about more operators, such as
  • Arithmetic assignment operators
  • Unary minus operators
  • Increment and decrement operators
  • Relational operators
  • Cast operator

Arithmetic Assignment Operators

Before jumping into the arithmetic assignment operators, you first need to learn more about the assignment operator.

The Assignment Operator (=)

In the C language, the = operator is called an assignment operator, which you've seen and used for several hours.
The general statement form to use an assignment operator is
left-hand-operand = right-hand-operand;
Here the statement causes the value of the right-hand-operand to be assigned (or written) to the memory location of the left-hand-operand. Additionally, the assignment statement itself returns the same value that is assigned to the left-hand-operand.
For example, the a = 5; statement writes the value of the right-hand operand (5) into the memory location of the integer variable a (which is the left-hand operand in this case).
Similarly, the b = a = 5; statement assigns 5 to the integer variable a first, and then to the integer variable b. After the execution of the statement, both a and b contain the value of 5.

WARNING
Don't confuse the assignment operator (=) with the relational operator, == (called the equal-to operator). The == operator is introduced later in this hour.

Combining Arithmetic Operators with =

Consider this example: Given two integer variables, x and y, how do you assign the sum of x and y to another integer variable, z?
By using the assignment operator (=) and the addition operator (+), you get the following statement:
z = x + y;
As you can see, it's pretty simple. Now, consider the same example again. This time, instead of assigning the result to the third variable, z, let's write the sum back to the integer variable, x:
x = x + y;
Here, on the right side of the assignment operator (=), the addition of x and y is executed; on the left side of =, the previous value saved by x is replaced with the result of the addition from the right side.
The C language gives you a new operator, +=, to do the addition and the assignment together. Therefore, you can rewrite the x = x + y; statement to
x += y;
The combinations of the assignment operator (=) with the arithmetic operators, +, -, *, /, and %, give you another type of operators—arithmetic assignment operators:
Operator Description
+= Addition assignment operator
-= Subtraction assignment operator
*= Multiplication assignment operator
/= Division assignment operator
%= Remainder assignment operator
The following shows the equivalence of statements:
x += y; is equivalent to x = x + y;
x -= y; is equivalent to x = x - y;
x *= y; is equivalent to x = x * y;
x /= y; is equivalent to x = x / y;
x %= y; is equivalent to x = x % y;

Note that the statement
z = z * x + y;
is not equivalent to the statement
z *= x + y;
because
z *= x + y
is indeed the same as
z = z * (x + y);
Listing 6.1 gives an example of using some of the arithmetic assignment operators.

TYPE
Listing 6.1. Using arithmetic assignment operators.

1:  /* 06L01.c: Using arithmetic assignment operators */
2:  #include <stdio.h>
3:
4:  main()
5:  {
6:     int x, y, z;
7:
8:     x = 1;   /* initialize x */
9:     y = 3;   /* initialize y */
10:    z = 10;  /* initialize z */
11:    printf("Given x = %d, y = %d, and z = %d,\n", x, y, z);
12:
13:    x = x + y;
14:    printf("x = x + y  assigns %d to x;\n", x);
15:
16:    x = 1;  /* reset x */
17:    x += y;
18:    printf("x += y  assigns %d to x;\n", x);
19:
20:    x = 1;  /* reset x */
21:    z = z * x + y;
22:    printf("z = z * x + y  assigns %d to z;\n", z);
23:
24:    z = 10;  /* reset z */
25:    z = z * (x + y);
26:    printf("z = z * (x + y) assigns %d to z;\n", z);
27:
28:    z = 10;  /* reset z */
29:    z *= x + y;
30:    printf("z *= x + y assigns %d to z.\n", z);
31:
32:    return 0;
33: }
OUTPUT
After this program is compiled and linked, an executable file is created. On my machine, this executable file is named as 06L01.exe. The following is the output printed on the screen after I run the executable from a DOS prompt:
C:\app> 06L01
Given x = 1, y = 3, and z = 10,
x = x + y  assigns 4 to x;
x += y  assigns 4 to x;
z = z * x + y  assigns 13 to z;
z = z * (x + y) assigns 40 to z;
z *= x + y assigns 40 to z.
C:\app>
ANALYSIS
Line 2 in Listing 6.1 includes the header file stdio.h by using the include directive in C. The stdio.h header file is needed for the printf() function used in the main() function body in lines 4_33.
Lines 8_10 initialize three integer variables, x, y, and z, which are declared in line 6. Line 11 then prints out the initial values assigned to x, y, and z.
The statement in line 13 uses the one addition operator and one assignment operator to add the values contained by x and y, and then assigns the result to x. Line 14 displays the result on the screen.
Similarly, lines 17 and 18 do the same addition and display the result again, after the variable x is reset in line 16. This time, the arithmetic assignment operator, +=, is used. Also, line 16 in Listing 6.1 resets the value of x to 1, before the addition.
The value of x is reset again in line 20. Line 21 performs a multiplication and an addition and saves the result to the integer variable z; that is, z = z * x + y;. The printf() function in line 22 displays the result, 13, on the screen. Again, the x = 1; statement in line 20 resets the integer variable, x.
Lines 24_30 display two results from two computations. The two results are actually the same (that is, 40), because the two computations in lines 25 and 29 are equivalent. The only difference between the two statements in lines 25 and 29 is that the arithmetic assignment operator, *=, is used in line 29.

Getting Negations of Numeric Numbers

If you want to change the sign of a numeric number, you can put the minus operator (-) right before the number. For instance, given an integer of 7, you can get its negation by changing the sign of the integer like this: -7. Here, - is the minus operator.
Precisely, - is called the unary minus operator in C. This is because the operator takes only one operand. The type of the operand can be any integer or floating-point number.
You can apply the unary minus operator to an integer or a floating-point variable as well. For example, given x = 1.234, -x equals -1.234. Or, given x = -1.234, -x equals 1.234.

WARNING
Don't confuse the unary minus operator with the subtraction operator, although both operators use the same symbol. For instance, the following statement:
z = x - -y;
z = x - (-y);
or this one:
z = x + y;
Here, in both statements, the first - symbol is used as the subtraction operator, while the second - symbol is the unary minus operator.

Incrementing or Decrementing by One

The increment and decrement operators are very handy to use when you want to add or subtract 1 from a variable. The symbol for the increment operator is ++. The decrement operator is --.
For instance, you can rewrite the statement x = x + 1; as ++x;, or you can replace x = x 1; with --x;.
Actually, there are two versions of the increment operator and of the decrement operator. In the ++x; statement, the increment operator is called the pre-increment operator, because the operator adds 1 to x first and then gets the value of x. Likewise, in the --x; statement, the pre-decrement operator first subtracts 1 from x and then gets the value of x.
If you have an expression like x++, you're using the post-increment operator. Similarly, in x--, the decrement operator is called the post-decrement operator.
For example, in the y = x++; statement, y is assigned the original value of x, not the one after x is increased by 1. In other words, the post-increment operator makes a copy of the original value of x and stores the copy in a temporary location. Then, x is increased by 1. However, instead of the modified value of x, the copy of the unmodified value of x is returned and assigned to y.
The post-decrement operator has a similar story. This operator returns a copy of the original value of a variable, rather than the current value of the variable (which has been decreased by 1).
The program in Listing 6.2 shows the differences between the two versions of increment operators and decrement operators.

TYPE
Listing 6.2. Using pre- or post-increment and decrement operators.

1:  /* 06L02.c: pre- or post-increment(decrement) operators */
2:  #include <stdio.h>
3:
4:  main()
5:  {
6:     int w, x, y, z, result;
7:
8:     w = x = y = z = 1;   /* initialize x and y */
9:     printf("Given w = %d, x = %d, y = %d, and z = %d,\n", w, x, y, z);
10:
11:    result = ++w;
12:    printf("++w gives: %d\n", result);
13:    result = x++;
14:    printf("x++ gives: %d\n", result);
15:    result = --y;
16:    printf("--y gives: %d\n", result);
17:    result = z--;
18:    printf("z-- gives: %d\n", result);
19:    return 0;
20: }
OUTPUT
The following result is obtained by running the executable file 06L02.exe:
C:\app> 06L02
Given w = 1, x = 1, y = 1, and z = 1,
++w gives: 2
x++ gives: 1
--y gives: 0
z-- gives: 1
C:\app>
ANALYSIS
Inside the main() function, line 8 in Listing 6.2 assigns 1 to each of the integer variables, w, x, y, and z. The printf() function in line 9 displays the values contained by the four integer variables.
Then, the statement in line 11 is executed and the result of the pre-increment of w is given to the integer variable result. In line 12, the value of result, which is 2, is printed out to the screen.
Lines 13 and 14 get the post-increment of x and print out the result. As you know, the result is obtained before the value of x is increased. Therefore, you see the numeric value 1 from the result of x++ on the screen.
The pre-decrement operator in line 15 causes the value of y to be reduced by 1 before the value is assigned to the integer variable result. Therefore, you see 0 as the result of --y shown on the screen.
In line 17, however, the post-decrement operator has no effect on the assignment because the original value of z is given to the integer variable result before z is decreased by 1. Line 18 thus prints out 1, which is the original value of z.

Greater Than or Less Than?

There are six types of relationships between two expressions: equal to, not equal to, greater than, less than, greater than or equal to, and less than or equal to. Accordingly, the C language provides six relational operators:
Operator Description
== Equal to
!= Not equal to
> Greater than
continues
Operator Description
< Less than
>= Greater than or equal to
<= Less than or equal to
All the relational operators have lower precedence than the arithmetic operators. Therefore, all arithmetic operations are carried out before any comparison is made. You should use parentheses to enclose operations of operators that have to be performed first.
Among the six operators, the >, <, >=, and <= operators have higher precedence than the == and != operators.
For example, the expression
x * y < z + 3
is interpreted as
(x * y) < (z + 3)
Another important thing is that all relational expressions produce a result of either 0 or 1. In other words, a relational expression returns 1 if the specified relationship holds. Otherwise, 0 is returned.
Given x = 3 and y = 5, for instance, the relational expression x < y gives a result of 1.
Listing 6.3 shows more examples of using relational operators.

TYPE
Listing 6.3. Results produced by relational expressions.

1:  /* 06L03.c: Using relational operators */
2:  #include <stdio.h>
3:
4:  main()
5:  {
6:     int x, y;
7:     double z;
8:
9:     x = 7;
10:    y = 25;
11:    z = 24.46;
12:    printf("Given x = %d, y = %d, and z = %.2f,\n", x, y, z);
13:    printf("x >= y  produces: %d\n", x >= y);
14:    printf("x == y  produces: %d\n", x == y);
15:    printf("x < z   produces: %d\n", x < z);
16:    printf("y > z   produces: %d\n", y > z);
17:    printf("x != y - 18  produces: %d\n", x != y - 18);
18:    printf("x + y != z   produces: %d\n", x + y != z);
19:    return 0;
20: }
OUTPUT
After the executable 06L03.exe is executed from a DOS prompt, the following output is displayed on the screen:
C:\app> 06L03
Given x = 7, y = 25, and z = 24.46,
x >= y  produces: 0
x == y  produces: 0
x < z   produces: 1
y > z   produces: 1
x != y - 18  produces: 0
x + y != z   produces: 1
C:\app>
ANALYSIS
There are two integer variables, x and y, and one floating-point variable z, declared in lines 6 and 7, respectively.
Lines 9_11 initialize the three variables. Line 12 prints out the values assigned to the variables.
Because the value of x is 7 and the value of y is 25, y is greater than x. Therefore, line 13 prints out 0, which is returned from the relational expression, x >= y.
Likewise, in line 14, the relational expression x == y returns 0.
Lines 15 and 16, however, print out the result of 1, returned from either x < z or y > z.
The statement in line 17 displays 0, which is the result of the relational expression x != y --18. In line 18, the expression x + y != z produces 1, which is output on the screen.

WARNING
Be careful when you compare two values for equality. Because of the truncation, or rounding up, some relational expressions, which are algebraically true, may return 0 instead of 1. For example, look at the following relational expression:
1 / 2 + 1 / 2 == 1
this is algebraically true and is supposed to return
The expression, however, returns 0, which means that the equal-to relationship does not hold. This is because the truncation of the integer division—that is, 1 / 2—produces 0, not 0.5.
Another example is 1.0 / 3.0, which produces 0.33333.... This is a number with an infinite number of decimal places. But the computer can only hold a limited number of decimal places. Therefore, the expression
1.0 / 3.0 + 1.0 / 3.0 + 1.0 / 3.0 == 1.0
might not return 1 on some computers, although the expression is theoretically true.

Playing with the Cast Operator

In C, you can convert one data type to a different one by prefixing the cast operator to the operand.
The general form of the cast operator is
(data-type)x
Here data-type specifies the data type you want to convert to. x is a variable (or, expression) that contains the value of the current data type. You have to include the parentheses ( and ) to make up a cast operator.
For example, the (float)5 expression converts the integer 5 to a floating-point number, 5.0.
The program in Listing 6.4 shows another example of using the cast operator.

TYPE
Listing 6.4. Using the cast operator.

1:  /* 06L04.c: Using the cast operator */
2:  #include <stdio.h>
3:
4:  main()
5:  {
6:     int x, y;
7:
8:     x = 7;
9:     y = 5;
10:    printf("Given x = %d, y = %d\n", x, y);
11:    printf("x / y produces: %d\n",  x / y);
12:    printf("(float)x / y produces: %f\n",  (float)x / y);
13:    return 0;
14: }
OUTPUT
The following output is obtained by running the executable 06L04.exe from a DOS prompt:
C:\app> 06L04
Given x = 7, y = 5
x / y produces: 1
(float)x / y produces: 1.400000
C:\app>
ANALYSIS
In Listing 6.4, there are two integer variables, x and y, declared in line 6, and initialized in lines 8 and 9, respectively. Line 10 then displays the values contained by the integer variables x and y.
The statement in line 11 prints out the integer division of x/y. Because the fractional part is truncated, the result of the integer division is 1.
However, in line 12, the cast operator (float) converts the value of x to a floating-point value. Therefore, the (float)x/y expression becomes a floating-point division that returns a floating-point number. That's why you see the floating-point number 1.400000 shown on the screen after the statement in line 12 is executed.

SOURCE LINK
Read More..

Reading from and Writing to Standard I/O

In the last lesson you learned how to print out characters, integers, and floating-point numbers to the screen by calling the printf() function. In this lesson you're going to learn more about printf(), as well as about the following functions, which are necessary to receive the input from the user or print the output to the screen:
  • The getc() function
  • The putc() function
  • The getchar() function
  • The putchar() function
Before we jump into these new functions, let's first get an idea about the standard input and output in C.

The Standard Input and Output (I/O)

A file contains related characters and numbers. Because all characters and numbers are represented in bits on computers, the C language treats a file as a series of bytes. (8 bits make up 1 byte.) A series of bytes is also called a stream. In fact, the C language treats all file streams equally, although some of the file streams may come from a disk or tape drive, from a terminal, or even from a printer.
Additionally, in C, there are three file streams that are pre-opened for you:
  • stdin–The standard input for reading.
  • stdout–The standard output for writing.
  • stderr–The standard error for writing error messages.
Usually, the standard input (stdin) file stream links to your keyboard, while the standard output (stdout) and the standard error (stderr) file streams point to your terminal screen. Also, many operating systems allow you to redirect these files' streams.
In fact, you've already used stdout. When you executed the printf() function in the last lesson, you were in fact sending the output to the default file stream, stdout, which points to your screen.
You'll learn more on stdin and stdout in the following sections.
NOTE
The C language provides many functions to manipulate file reading and writing (I/O). The header file stdio.h contains the declarations for those functions. Therefore, always include the header file stdio.h in your C program before doing anything with the file I/O.

Getting the Input from the User

In these days, typing from keyboard is still the de facto standard way to input information into computers. The C language has several functions to direct the computer to read the input from the user (typically through the keyboard.) In this lesson the getc() and getchar() functions are introduced.

Using the getc() Function

The getc() function reads the next character from a file stream, and returns the character as an integer.

The syntax for the getc() function is
#include <stdio.h>

int getc(FILE *stream);
Here FILE *stream declares a file stream (that is, a variable). The function returns the numeric value of the character read. If an end-of-file or error occurs, the function returns EOF.
At this moment, don't worry about the FILE structure. More details about it are introduced in Hours 21, "Disk File Input and Output: Part I," and 22, "Disk File Input and Output: Part II." In this section, the standard input stdin is used as the file stream specified by FILE *stream.
NOTE
Defined in the header file stdio.h, EOF is a constant. EOF stands for end-of-file. Usually, the value of EOF is -1. But keep using EOF, instead of -1, if you need an end-of-file indicator, in case a compiler uses a different value.
Listing 5.1 shows an example that reads a character typed in by the user from the keyboard and then displays the character on the screen.

TYPE
Listing 5.1. Reading in a character entered by the user.

1:  /* 05L01.c: Reading input by calling getc() */

2:  #include <stdio.h>

3:

4:  main()

5:  {

6:     int ch;

7:

8:     printf("Please type in one character:\n");

9:     ch = getc( stdin );

10:    printf("The character you just entered is: %c\n", ch);

11:    return 0;

12: }
The following is the output displayed on the screen after I run the executable file, 05L01.exe, enter the character H, and press the Enter key:
C:\app> 05L01

Please type in one character:

H

The character you just entered is: H

C:\app>
OUTPUT
You see in line 2 of Listing 5.1 that the header file stdio.h is included for both the getc() and printf() functions used in the program. Lines 4_12 give the name and body of the main() function.
ANALYSIS
In line 6, an integer variable, ch, is declared; it is assigned the return value from the getc() function later in line 9. Line 8 prints out a piece of message that asks the user to enter one character from the keyboard. As I mentioned earlier in this lesson, the printf() function in line 8 uses the default standard output stdout to display messages on the screen.
In line 9, the standard input stdin is passed to the getc() function, which indicates that the file stream is from the keyboard. After the user types in a character, the getc() function returns the numeric value (that is, an integer) of the character. You see that, in line 9, the numeric value is assigned to the integer variable ch.
Then, in line 10, the character entered by the user is displayed on the screen with the help of printf(). Note that the character format specifier (%c) is used within the printf() function in line 10. (Exercise 1 in this lesson asks you to use %d in a program to print out the numeric value of a character entered by the user.)

Using the getchar() Function

The C language provides another function, getchar(), to perform a similar operation to getc(). More precisely, the getchar() function is equivalent to getc(stdin).
The syntax for the getchar() function is
#include <stdio.h>

int getchar(void);
Here void indicates that no argument is needed for calling the function. The function
returns the numeric value of the character read. If an end-of-file or error occurs, the function returns EOF.
The program in Listing 5.2 demonstrates how to use the getchar() function to read the input from the user.

TYPE
Listing 5.2. Reading in a character by calling getchar().

1:  /* 05L02.c: Reading input by calling getchar() */

2:  #include <stdio.h>

3:

4:  main()

5:  {

6:     int ch1, ch2;

7:

8:     printf("Please type in two characters together:\n");

9:     ch1 = getc( stdin );

10:    ch2 = getchar( );

11:    printf("The first character you just entered is: %c\n", ch1);

12:    printf("The second character you just entered is: %c\n", ch2);

13:    return 0;

14: }
OUTPUT
After running the executable file, 05L02.exe, and entering two characters (H and i) together without spaces, I press the Enter key and the following output is displayed on the screen:
C:\app> 05L02

Please type in two characters together:

Hi

The first character you just entered is: H

The second character you just entered is: i

C:\app>
ANALYSIS
The program in Listing 5.2 is quite similar to the one in Listing 5.1, except that the former reads in two characters.
The statement in line 6 declares two integers, ch1 and ch2. Line 8 displays a message asking the user to enter two characters together.
Then, the getc() and getchar() functions are called in lines 9 and 10, respectively, to read in two characters entered by the user. Note that in line 10, nothing is passed to the getchar() function. This is because, as mentioned earlier, getchar() has its default file stream–stdin. You can replace the getchar() function in line 10 with getc(stdin), because getc(stdin) is equivalent to getchar().
Lines 11 and 12 send two characters (kept by ch1 and ch2, respectively) to the screen.

Printing the Output on the Screen

Besides getc() and getchar() for reading, the C language also provides two functions, putc() and putchar(), for writing. The following two sections introduce these functions.

Using the putc() Function

The putc() function writes a character to the specified file stream, which, in our case, is the standard output pointing to your screen.
The syntax for the putc() function is
#include <stdio.h>

int putc(int c, FILE *stream);
Here the first argument, int c, indicates that the output is a character saved in an integer variable c; the second argument, FILE *stream, specifies a file stream. If successful, putc() returns the character written; otherwise, it returns EOF.
In this lesson the standard output stdout is used to be the specified file stream in putc().
The putc() function is used in Listing 5.3 to put the character A on the screen.

TYPE
Listing 5.3. Putting a character on the screen.

1:  /* 05L03.c: Outputting a character with putc() */

2:  #include <stdio.h>

3:

4:  main()

5:  {

6:     int ch;

7:

8:     ch = 65;   /* the numeric value of A */

9:     printf("The character that has numeric value of 65 is:\n");

10:    putc(ch, stdout);

11:    return 0;

12: }
OUTPUT
The following is what I get from my machine:
C:\app> 05L03

The character that has numeric value of 65 is:

A

C:\app>
ANALYSIS
As mentioned, the header file stdio.h, containing the declaration of putc(), is included in line 2.
The integer variable, ch, declared in line 6, is assigned the numeric value of 65 in line 8. You may remember that 65 is the numeric value of character A.
Line 9 displays a message to remind the user of the numeric value of the character that is going to be put on the screen. Then, the putc() function in line 10 puts character A on the screen. Note that the first argument to the putc() function is the integer variable (ch) that contains 65, and the second argument is the standard output file stream, stdout.

Another Function for Writing: putchar()

Like putc(), putchar() can also be used to put a character on the screen. The only difference between the two functions is that putchar() needs only one argument to contain the character. You don't need to specify the file stream, because the standard output (stdout) is the default file stream to putchar().
The syntax for the putchar() function is
#include <stdio.h>

int putchar(int c);
Here int c is the argument that contains the numeric value of a character. The function returns EOF if an error occurs; otherwise, it returns the character that has been written.
An example of using putchar() is demonstrated in Listing 5.4.

TYPE
Listing 5.4. Outputting characters with putchar().

1:  /* 05L04.c: Outputting characters with putchar() */

2:  #include <stdio.h>

3:

4:  main()

5:  {

6:     putchar(65);

7:        putchar(10);

8:           putchar(66);

9:              putchar(10);

10:          putchar(67);

11:       putchar(10);

12:    return 0;

13: }
OUTPUT
After running the executable file, 05L04.exe, I get the following output:
C:\app> 05L04

A

B

C

C:\app>
ANALYSIS
The way to write the program in Listing 5.4 is a little bit different. There is no variable declared in the program. Rather, integers are passed to putchar() directly, as shown in lines 6_11.
As you might have figured out, 65, 66, and 67 are, respectively, the numeric values of characters A, B, and C. From exercise 5 of Hour 4, "Data Types and Names in C," or from Appendix C, "ASCII Character Set," you can find out that 10 is the numeric value of the newline character (\n).
Therefore, respectively, lines 6 and 7 put character A on the screen and cause the computer to start at the beginning of the next line. Likewise, line 8 puts B on the screen, and line 9 starts a new line. Then, line 10 puts C on the screen, and line 11 starts another new line. Accordingly, A, B, and C, are put at the beginnings of three consecutive lines, as shown in the output section.

Revisiting the printf() Function

The printf() function is the first C library function you used in this book to print out messages on the screen. printf() is a very important function in C, so it's worth it to spend more time on it.
The syntax for the printf() function is
#include <stdio.h>

int printf(const char *format-string, ...);
Here const char *format-string is the first argument that contains the format specifier(s); ... indicates the expression section that contains the expression(s) to be formatted according to the format specifiers. The number of expressions is determined by the number of the format specifiers inside the first argument. The function returns the numbers of expressions formatted if it succeeds. It returns a negative value if an error occurs.
const char * is explained later in this book. For the time being, consider the first argument to the printf() function as a series of characters surrounded with double quotes with some format specifiers inside. For instance, you can pass "The sum of two integers %d + %d is: %d.\n" to the function as the first argument, if needed.
Figure 5.1 shows the relationship between the format string and expressions. Note that the format specifiers and the expressions are matched in order from left to right.

Figure 5.1. The relation between the format string and the expressions in printf().
Please remember that you should use exactly the same number of expressions as the number of format specifiers within the format string.
The following are all the format specifiers that can be used in printf():

%c The character format specifier.
%d The integer format specifier.
%i The integer format specifier (same as %d).
%f The floating-point format specifier.
%e The scientific notation format specifier (note the lowercase e).
%E The scientific notation format specifier (note the uppercase E).
%g Uses %f or %e, whichever result is shorter.
%G Uses %f or %E, whichever result is shorter.
%o The unsigned octal format specifier.
%s The string format specifier.
%u The unsigned integer format specifier.
%x The unsigned hexadecimal format specifier (note the lowercase x).
%X The unsigned hexadecimal format specifier (note the uppercase X).
%p Displays the corresponding argument that is a pointer.
%n Records the number of characters written so far.
%% Outputs a percent sign (%).
Among the format specifiers in this list, %c, %d, %f, %e, and %E have been introduced so far. Several others are explained later in this book. The next section shows you how to convert decimal numbers to hexadecimal numbers by using %x or %X.

Converting to Hex Numbers

The difference between a decimal number and a hexadecimal number is that the hexadecimal is a base-16 numbering system. A hexadecimal number can be represented by four bits. (24 is equal to 16, which means four bits can produce 16 unique numbers.) Hexadecimal is often written as hex for short.
The hexadecimal numbers 0 through 9 use the same numeric symbols founded in the decimal numbers 0 through 9. uppercase A, B, C, D, E, and F are used to represent, respectively, the hexadecimal numbers 10 through 15. (Similarly, in lowercase, a, b, c, d, e, and f are used to represent these hex numbers.)
Listing 5.5 provides an example of converting decimal numbers to hex numbers by using %x or %X in the printf() function.

TYPE
Listing 5.5. Converting to hex numbers.

1:  /* 05L05.c: Converting to hex numbers */

2:  #include <stdio.h>

3:

4:  main()

5:  {

6:     printf("Hex(uppercase)    Hex(lowercase)    Decimal\n");

7:     printf("%X                %x                %d\n", 0, 0, 0);

8:     printf("%X                %x                %d\n", 1, 1, 1);

9:     printf("%X                %x                %d\n", 2, 2, 2);

10:    printf("%X                %x                %d\n", 3, 3, 3);

11:    printf("%X                %x                %d\n", 4, 4, 4);

12:    printf("%X                %x                %d\n", 5, 5, 5);

13:    printf("%X                %x                %d\n", 6, 6, 6);

14:    printf("%X                %x                %d\n", 7, 7, 7);

15:    printf("%X                %x                %d\n", 8, 8, 8);

16:    printf("%X                %x                %d\n", 9, 9, 9);

17:    printf("%X                %x                %d\n", 10, 10, 10);

18:    printf("%X                %x                %d\n", 11, 11, 11);

19:    printf("%X                %x                %d\n", 12, 12, 12);

20:    printf("%X                %x                %d\n", 13, 13, 13);

21:    printf("%X                %x                %d\n", 14, 14, 14);

22:    printf("%X                %x                %d\n", 15, 15, 15);

23:    return 0;

24: }
OUTPUT
The following output is obtained by running the executable file, 05L05.exe, on my machine:
C:\app> 05L05

Hex(uppercase)   Hex(lowercase)   Decimal

0                0                0

1                1                1

2                2                2

3                3                3

4                4                4

5                5                5

6                6                6

7                7                7

8                8                8

9                9                9

A                a                10

B                b                11

C                c                12

D                d                13

E                e                14

F                f                15

C:\app>

ANALYSIS
Don't panic when you see so many printf() functions being used in Listing 5.5. In fact, the program in Listing 5.5 is very simple. The program has just one function body from lines 5_23.
The printf() function in line 6 prints out a headline that contains three fields: Hex(uppercase), Hex(lowercase), and Decimal.
Then, lines 7_22 print out the hex and decimal numbers 0 through 15. Sixteen printf() functions are called to accomplish the job. Each of the printf() functions has a format string as the first argument followed by three integers as three expressions. Note that the hex format specifiers %X and %x are used within the format string in each of the printf() functions to convert the corresponding expressions to the hex format (both uppercase and lowercase).
In reality, nobody would write a program like the one in Listing 5.5. Instead, a loop can be used to call the printf() function repeatedly. Looping (or iteration) is introduced in Hour 7, "Doing the Same Thing Over and Over."

Adding the Minimum Field Width

The C language allows you to add an integer between the percent sign (%) and the letter in a format specifier. The integer is called the minimum field width specifier because it specifies the minimum field width and ensures that the output reaches the minimum width. For example, in %10f, 10 is a minimum field width specifier that ensures that the output is at least 10 character spaces wide.
The example in Listing 5.6 shows how to use the minimum field width specifier.

TYPE
Listing 5.6. Specifying the minimum field width.

1:  /* 05L06.c: Specifying minimum field width */

2:  #include <stdio.h>

3:

4:  main()

5:  {

6:     int num1, num2;

7:

8:     num1 = 12;

9:     num2 = 12345;

10:    printf("%d\n", num1);

11:    printf("%d\n", num2);

12:    printf("%5d\n", num1);

13:    printf("%05d\n", num1);

14:    printf("%2d\n", num2);

15:    return 0;

16: }

OUTPUT
The following is the result I obtain by running the executable file 05L06.exe:
C:\app> 05L06

12

12345

   12

00012

12345

C:\app>
ANALYSIS
In Listing 5.6, two integer variables, num1 and num2, are declared in line 6, and assigned 12 and 12345, respectively, in lines 8 and 9.
Without using any minimum field width specifiers, lines 10 and 11 print out the two integers by calling the printf() function. You can see in the output section that the output made by the statements in line 10 is 12, which takes two character spaces, while the output, 12345, from line 11 takes five character spaces.
In line 12, a minimum field width, 5, is specified by %5d. The output from line 12 therefore takes five character spaces, with three blank spaces plus two character spaces of 12. (See the third output line in the output section.)
The %05d in printf(), shown in line 13, indicates that the minimum field width is 5, and zeros are used to pad the spaces. Therefore, you see the output made by the execution of the statement in line 13 is
00012
The %2d in line 14 sets the minimum field width to 2, but you still see the full-size output of 12345 from line 14. This means that when the minimum field width is shorter than the width of the output, the latter is taken, and the output is still printed in full.

Aligning Output

As you might have noticed in the previous section, all output is right-justified. In other words, by default, all output is placed on the right edge of the field, as long as the field width is longer than the width of the output.
You can change this and force output to be left-justified. To do so, you need to prefix the minimum field specifier with the minus sign (-). For example, %-12d specifies the minimum field width as 12, and justifies the output from the left edge of the field.
Listing 5.7 gives an example of aligning output by left- or right-justification.

TYPE
Listing 5.7. Left- or right-justified output.


1:  /* 05L07.c: Aligning output */

2:  #include <stdio.h>

3:

4:  main()

5:  {

6:     int num1, num2, num3, num4, num5;

7:

8:     num1 = 1;

9:     num2 = 12;

10:    num3 = 123;

11:    num4 = 1234;

12:    num5 = 12345;

13:    printf("%8d  %-8d\n", num1, num1);

14:    printf("%8d  %-8d\n", num2, num2);

15:    printf("%8d  %-8d\n", num3, num3);

16:    printf("%8d  %-8d\n", num4, num4);

17:    printf("%8d  %-8d\n", num5, num5);

18:    return 0;

19: }
OUTPUT
I get the following output displayed on the screen after I run the executable 05L07.exe from a DOS prompt on my machine:
C:\app> 05L07

       1  1

      12  12

     123  123

    1234  1234

   12345  12345

C:\app>
ANALYSIS
In Listing 5.7, there are five integer variables, num1, num2, num3, num4, and num5, that are declared in line 6 and are assigned values in lines 8_12.
These values represented by the five integer variables are then printed out by the printf() functions in lines 13_17. Note that all the printf() functions have the same first argument: "%8d %-8d\n". Here the first format specifier, %8d, aligns the output at the right edge of the field, and the second specifier, %-8d, does the alignment by justifying the output from the left edge of the field.
After the execution of the statements in lines 13_17, the alignment is accomplished and the output is put on the screen like this:
1  1

      12  12

     123  123

    1234  1234

   12345  12345

Using the Precision Specifier

You can put a period (.) and an integer right after the minimum field width specifier. The combination of the period (.) and the integer makes up a precision specifier. The precision specifier is another important specifier you can use to determine the number of decimal places for floating-point numbers, or to specify the maximum field width (or length) for integers or strings. (Strings in C are introduced in Hour 13, "Manipulating Strings.")
For instance, with %10.3f, the minimum field width length is specified as 10 characters long, and the number of decimal places is set to 3. (Remember, the default number of decimal places is 6.) For integers, %3.8d indicates that the minimum field width is 3, and the maximum field width is 8.
Listing 5.8 gives an example of left- or right-justifying output by using precision specifiers.

TYPE
Listing 5.8. Using precision specifiers.

1:  /* 05L08.c: Using precision specifiers */

2:  #include <stdio.h>

3:

4:  main()

5:  {

6:     int int_num;

7:     double flt_num;

8:

9:     int_num = 123;

10:    flt_num = 123.456789;

11:    printf("Default integer format:    %d\n", int_num);

12:    printf("With precision specifier:  %2.8d\n", int_num);

13:    printf("Default float format:      %f\n", flt_num);

14:    printf("With precision specifier:  %-10.2f\n", flt_num);

15:    return 0;

16: }
OUTPUT
After running the executable file 05L08.exe on my machine, I get the following output on the screen:
C:\app> 05L08

Default integer format:    123

With precision specifier:  00000123

Default float format:      123.456789

With precision specifier:  123.46

C:\app>
ANALYSIS
The program in Listing 5.8 declares one integer variable, int_num, in line 6, and one floating-point number, flt_num, in line 7. Lines 9 and 10 assign 123 and 123.456789 to int_num and flt_num, respectively.
In line 11, the default integer format is specified for the integer variable, int_num, while the statement in line 12 specifies the integer format with a precision specifier that indicates that the maximum field width is 8 characters long. Therefore, you see that five zeros are padded prior to the integer 123 in the second line of the output.
For the floating-point variable, flt_num, line 13 prints out the floating-point value in the default format, and line 14 reduces the decimal places to two by putting the precision specifier .2 within the format specifier %-10.2f. Note here that the left-justification is also specified by the minus sign (-) in the floating-point format specifier.
The floating-point number 123.46 in the fourth line of the output is produced by the statement in line 14 with the precision specifier for two decimal places. Therefore, 123.456789 rounded to two decimal places becomes 123.46.

SOURCE LINK
Read More..