Sams Teach Yourself C in 24 Hours (25 page)

BOOK: Sams Teach Yourself C in 24 Hours
12.17Mb size Format: txt, pdf, ePub

Therefore, num%2 yields the remainder of num divided by 2. The relational expression num%2 == 0 yields 1 if the remainder is equal to 0—that is, the value of num can be divided by 2 completely. Likewise, if the value of num can be divided by 3, the relational 11 067231861x CH08 4.10.2000 11:02 AM Page 126

126

Hour 8

expression num%3 == 0 yields 1 as well. Then, according to the truth table of the && operator (see Table 8.1), you know that the combination of the logical AND operator (&&) and the two relational expressions yields 1 if the two relational expressions both evaluate to nonzero; 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 zero so that the two relational expressions evaluate to 1. Therefore, the logical AND

operator yields 1.

However, when num is assigned the value of 2 or 3 as shown in lines 11 and 14, the logical AND operator in line 13 or line 16 yields 0. The reason is that 2 or 3 can not 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 yields 1 which is printed out by the printf() function in lines 18 and 19.

The Logical OR Operator (
||
)

As mentioned earlier, the logical OR operator yields 1 (logically true) if one or both of the expressions evaluates to a nonzero value. The || operator yields 0 if (and only if) both expressions yield 0.

A general format of the logical OR operator is:

exp1 || exp2

where exp1 and exp2 are two operand expressions evaluated by the OR operator.

Table 8.2 is the truth table of the OR operator.

TABLE 8.2

The Values Returned by the OR Operator

exp1

exp2

|| Yields

nonzero

nonzero

1

nonzero

0

1

0

nonzero

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

11 067231861x CH08 4.10.2000 11:02 AM Page 127

Using Conditional Operators

127

3:

4: main()

5: {

8

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() – ‘0’;

11: printf(“You got such a number: %d\n”, num);

12: return 0;

13: }

The following is the output displayed after the executable file 08L03.exe is run on my machine. The numbers in bold are what I entered. (The Enter key is pressed each time after one of the numbers is entered.) In the range of 0–9, 0 and 6 are the only two numbers that can be completely divided by both 2 and 3:

Enter a single digit that can be divided

OUTPUT
by both 2 and 3:

2

3

4

5

6

You got such a number: 6 In Listing 8.3, an integer variable, num, is declared in
ANALYSIS
line 6. Line 8 of Listing 8.3 prints out two headlines asking the user to enter a single digit.

In line 9, the integer variable num is initialized in the first expression of the for statement. The reason to initialize num with 1 is because 1 is such a number that is divisible by neither 2 nor 3. This way, 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 two relational expressions num%2 != 0 and num%3 != 0 are evaluated.

According to the truth table of the || operator (see Table 8.2), you know that if one of the relational expression evaluates to nonzero, indicating in this case that the value of num cannot be divided completely by either 2 or 3, then the logical OR expression evaluates to 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 of the relational expressions evaluate to 0, the logical OR operator yields 0, which causes the termination of the for loop.

11 067231861x CH08 4.10.2000 11:02 AM Page 128

128

Hour 8

The Logical NEGATION Operator (
!
)

The general format of using the logical NEGATION operator is:

!expression

where expression is the operand of 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
!

nonzero

0

0

1

Now, let’s take a look at the example shown in Listing 8.4, which demonstrates how to use the logical negation operator (!).

TYPE

LISTING 8.4

Using the Logical Negation Operator (!)

1: /* 08L04.c: Using the logical negation operator */

2: #include

3:

4: main()

5: {

6: int num;

7:

8: num = 7;

9: printf(“Given num = 7\n”);

10: printf(“!(num < 7) yields: %d\n”, !(num < 7));

11: printf(“!(num > 7) yields: %d\n”, !(num > 7));

12: printf(“!(num == 7) yields: %d\n”, !(num == 7));

13: return 0;

14: }

The following result is displayed by running the executable file 08L04.exe: Given num = 7

OUTPUT
!(num < 7) returns: 1

!(num > 7) returns: 1

!(num == 7) returns: 0

In line 8, note that an integer variable num is initialized to 7, which is then dis-ANALYSIS played by the printf() function in line 9.

11 067231861x CH08 4.10.2000 11:02 AM Page 129

Using Conditional Operators

129

In line 10, the relational expression num < 7 evaluates to 0 because the value of num is not less than 7. However, by using the logical negation operator, !(num < 7) yields 1.

8

(Refer to the truth table of the ! operator shown in Table 8.3.)

Similarly, the logical expression !(num > 7) evaluates to 1 in line 11.

Because num has the value of 7, the relational expression num == 7 yields 1; however, the logical expression !(num == 7) in line 12 evaluates to 0.

Manipulating Bits

In previous hours, you learned that computer data and files are made of bits. In this section, you’ll learn about a set of operators that enable you to access and manipulate specific bits. But before we go further, let us learn more about binary and hex numbers, and how to convert a decimal number to its binary or hex representation.

Converting Decimal to Hex or Binary

As I mentioned before, a bit is the smallest storage unit in the computer world. A bit can only hold the values 0 and 1 (0 and 1 are used to represent the off and on states of electronic switches that make up a computer’s CPU and memory.) Each digit of a hex number consists of 4 bits. It is easy to convert a decimal number into a hex or a binary number. Table 8.4 shows the hex numbers from 0 to 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

continues

11 067231861x CH08 4.10.2000 11:02 AM Page 130

130

Hour 8

TABLE 8.4

continued

Hex

Binary

Decimal

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 a hex number, or vice versa.

As you know, 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, the bit can have a value of either 0 or 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 rightmost bit is at the position of zero.

Thus, given a binary number 1000 (its hex value is 8), we can calculate its decimal value like this:

3

2

1

0

3

1000 → 1 * 2 + 0 * 2 + 0 * 2 + 0 * 2 → 2 → 8 (decimal)

That is, the decimal value of the binary number 1000 is 8.

Similarly, given a binary number 1110, its hex value is E, you can calculate its decimal value like this:

3

2

1

0

3

1110 → 1 * 2 + 1 * 2 + 1 * 2 + 0 * 2 → 2 → 14 (decimal)

In other words, the decimal value of the binary number 1110 is 14.

If you want to convert a decimal number, for example 10, to its binary counterpart, you have the following process:

3

1

3

2

1

0

10 → 2 + 2 → 1 * 2 + 0 * 2 + 1 * 2 + 0 * 2 → 1010 (binary) or A (hex)

Likewise, you can convert the rest of decimal numbers in Table 8.4 to their binary counterparts, or vice versa.

Using Bitwise Operators

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

11 067231861x CH08 4.10.2000 11:02 AM Page 131

Using Conditional Operators

131

Operator

Description

~

The bitwise complement operator

8

>>

The right-shift operator

<<

The left-shift operator

This section and the next one give explanations and examples of the bit-manipulation 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 or both of the bits is 0, 0 is placed in the result.

For instance, the expression with two binary operands, 01 & 11, yields 01.

The | operator places 1 in the result if either operand is 1. For example, the expression 01 | 11 yields 11. The | operator yields a 0 bit if — and only if — both operand bits are 0.

The ^ operator places 1 in the result if exactly one operand, but not both, is 1. Therefore, the expression 01 ^ 11 yields 10.

Finally, the ~ operator takes just one operand. This operator reverses each bit in the operand. For instance, ~01 gives 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 Using Bitwise Operators

Expressions

Results

Decimal

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

11 067231861x CH08 4.10.2000 11:02 AM Page 132

132

Hour 8

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, “Working with Data Modifiers and Math Functions.”)

The program in Listing 8.5 demonstrates the usage of the bitwise operators.

TYPE

LISTING 8.5

Using Bitwise Operators

1: /* 08L05.c: Using bitwise operators */

2: #include

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: }

After the executable file, 08L05.exe, is created and run on my computer, the following output is shown on the screen:

Given x = 4321, i.e., 0X10E1

OUTPUT

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

Other books

Trout and Me by Susan Shreve
The Reach of a Chef by Michael Ruhlman
Edge of Surrender by Laura Griffin
The Mamacita Murders by Debra Mares
All the Tea in China by Jane Orcutt
The Buried Circle by Jenni Mills
Plot It Yourself by Stout, Rex
A Vintage From Atlantis by Clark Ashton Smith
Social Engineer by Ian Sutherland