Read Sams Teach Yourself C in 24 Hours Online
Authors: Tony. Zhang
This section shows you that you can write a new value to the memory location of a variable using a pointer that contains the left value of the variable. Listing 11.3 shows an example.
TYPE
LISTING 11.3
Changing Variable Values Via Pointers
1: /* 11L03.c: Changing values via pointers */
2: #include
3:
4: main()
5: {
6: char c, *ptr_c;
7:
8: c = ‘A’;
9: printf(“c: address=%p, content=%c\n”, &c, c);
10: ptr_c = &c;
11: printf(“ptr_c: address=%p, content=%p\n”, &ptr_c, ptr_c); 12: printf(“*ptr_c => %c\n”, *ptr_c);
13: *ptr_c = ‘B’;
14: printf(“ptr_c: address=%p, content=%p\n”, &ptr_c, ptr_c);
continues
15 067231861x CH11 1/25/00 10:16 AM Page 184
184
Hour 11
LISTING 11.3
continued
15: printf(“*ptr_c => %c\n”, *ptr_c);
16: printf(“c: address=%p, content=%c\n”, &c, c);
17: return 0;
18: }
After running the executable file 11L03.exe on my machine, I get the following output displayed on the screen:
c: address=0x1828, content=A
OUTPUT
ptr_c: address=0x1826, content=0x1828
*ptr_c => A
ptr_c: address=0x1826, content=0x1828
*ptr_c => B
c: address=0x1828, content=B
A char variable, c, and a char pointer variable, ptr_c, are declared in line 6 of
ANALYSIS
Listing 11.3.
The variable c is initialized with ‘A’ in line 8, which is printed out, along with the address of the variable, by the printf() function in line 9.
In line 10, the pointer variable ptr_c is assigned the left value (address) of c. It’s not surprising to see the output printed out by the statements in lines 11 and 12, where the right value of ptr_c is the left value of c, and the pointer *ptr_c points to the right value of c.
In line 13 the expression *ptr_c = ‘B’ asks the computer to write ‘B’ to the location pointed to by the pointer ptr_c. The output printed by the statement in line 15 proves that the content of the memory location pointed to by ptr_c is updated. The statement in line 14 prints out the left and right values of the pointer variable ptr_c and shows that these values remain the same. As you know, the location pointed to by ptr_c is where the character variable c resides. Therefore, the expression *ptr_c = ‘B’ actually updates the content (that is, the right value) of the variable c to ‘B’. To prove this, the statement in line 16 displays the left and right values of c on the screen. Sure enough, the output shows that the right value of c has been changed.
Pointing to the Same Memory Location
A memory location can be pointed to by more than one pointer. For example, given that c = ‘A’ and that ptr_c1 and ptr_c2 are two character pointer variables, ptr_c1 = &c and ptr_c2 = &c set the two pointer variables to point to the same location in the memory.
15 067231861x CH11 1/25/00 10:16 AM Page 185
Understanding Pointers
185
The program in Listing 11.4 shows another example of pointing to the same thing with several pointers.
LISTING 11.4
Pointing to the Same Memory Location with More
TYPE
Than One Pointer
1: /* 11L04.c: Pointing to the same thing */
2: #include
3:
4: main()
5: {
6: int x;
7: int *ptr_1, *ptr_2, *ptr_3;
8:
9: x = 1234;
10: printf(“x: address=%p, content=%d\n”, &x, x);
11: ptr_1 = &x;
12: printf(“ptr_1: address=%p, content=%p\n”, &ptr_1, ptr_1);
13: printf(“*ptr_1 => %d\n”, *ptr_1);
14: ptr_2 = &x;
15: printf(“ptr_2: address=%p, content=%p\n”, &ptr_2, ptr_2);
16: printf(“*ptr_2 => %d\n”, *ptr_2);
17: ptr_3 = ptr_1;
11
18: printf(“ptr_3: address=%p, content=%p\n”, &ptr_3, ptr_3);
19: printf(“*ptr_3 => %d\n”, *ptr_3);
20: return 0;
21: }
The following output is displayed on the screen by running the executable file 11L04.exe on my machine (note that you might get different address values depending on the your system):
x: address=0x1838, content=1234
OUTPUT
ptr_1: address=0x1834, content=0x1838
*ptr_1 => 1234
ptr_2: address=0x1836, content=0x1838
*ptr_2 => 1234
ptr_3: address=0x1832, content=0x1838
*ptr_3 => 1234
As shown in Listing 11.4, line 6 declares an integer variable, x, and line 7
ANALYSIS
declares three integer pointer variables, ptr_1, ptr_2, and ptr_3.
The statement in line 10 prints out the left and right values of x. On my machine, the left value (address) of x is 0x1838. The right value (content) of x is 1234, which is the initial value assigned to x in line 9
15 067231861x CH11 1/25/00 10:16 AM Page 186
186
Hour 11
Line 11 assigns the left value of x to the pointer variable ptr_1 so that ptr_1 can be used to refer to the right value of x. To make sure that the pointer variable ptr_1 now contains the address of x, line 12 prints out the right value of ptr_1, along with its left value. The output shows that ptr_1 does hold the address of x, 0x1838. Then, line 13 prints out the value 1234, which is referred to by the *ptr_1 expression. Note that the asterisk * in the expression is the dereference operator
In line 14, the *ptr_2 = &x expression assigns the left value of x to another pointer variable, ptr_2; that is, the pointer variable ptr_2 is now linked with the address of x. The statement in line 16 displays the integer 1234 on the screen by using the dereference operator * and its operand, ptr_2. In other words, the memory location of x is referred to by the second pointer *ptr_2.
In line 17, the pointer variable ptr_3 is assigned the right value of ptr_1. Because ptr_1
now holds the address of x, the expression ptr_3 = ptr_1 is equivalent to ptr_3 = &x.
Then, from the output made by the statements in lines 18 and 19, you see the integer 1234 again on the screen. This time the integer is referred to by the third pointer, ptr_3.
Summary
In this lesson you learned the following very important concepts about pointers in C:
• A pointer is a variable whose value points to another variable.
• A variable declared in C has two values: the left value and the right value.
• The left value of a variable is the address; the right value is the content of the variable.
• The address-of operator (&) can be used to obtain the left value (address) of a variable.
• The asterisk (*) in a pointer declaration tells the compiler that the variable is a pointer variable.
• The dereference operator (*) is a unary operator; as such, it requires only one operand.
• The *ptr_name expression evaluates to the value pointed to by the pointer variable ptr_name, where ptr_name can be any valid variable name in C.
• If the pointer variable’s right value has been assigned the value 0, the pointer is a null pointer. A null pointer cannot point to valid data.
• You can update the value of a variable referred by a pointer variable.
• Several pointers can point to the same location of a variable in the memory.
15 067231861x CH11 1/25/00 10:16 AM Page 187
Understanding Pointers
187
You will see more examples of using pointers in the rest of the book.
In the next lesson you’ll learn about an aggregate type—an array, which is closely related to pointers in C.
Q&A
Q What are the left and right values?
A
The left value is the address of a variable, and the right value is the content stored in the memory location of a variable. There are two ways to get the right value of a variable: use the variable name directly, or use the left value of the variable and the dereference operator to refer to where the right value resides. The second way is also called the indirect way.
Q How can you obtain the address of a variable?
A
By using the address-of operator, &. For instance, given an integer variable x, the
&x expression evaluates to the address of x. To print out the address of x, you can use the %p format specifier in the printf() function.
Q What is the concept of indirection in terms of using pointers?
11
A
Before this hour, the only way you knew for reading from or writing to a variable was to invoke the variable directly. For instance, if you wanted to write a decimal, 16, to an integer variable x, you could use the statement x = 16;.
As you learned in this hour, C allows you to access a variable in another way—
using pointers. Therefore, to write 16 to x, you can first declare an integer pointer (ptr) and assign the left value (address) of x to ptr—that is, ptr = &x;. Then, instead of executing the statement x = 16;, you can use another statement:
*ptr = 16;
Here the pointer *ptr refers to the memory location reserved by x, and the content stored in the memory location is updated to 16 after the statement is executed. So, you see, making use of pointers to access the memory locations of variables is a way of indirection.
Q Can a null pointer point to valid data?
A
No. A null pointer cannot point to valid data. This is because the value contained by a null pointer has been set to 0. You’ll see examples of using null pointers in arrays, strings, and memory allocation later in the book.
15 067231861x CH11 1/25/00 10:16 AM Page 188
188
Hour 11
Workshop
To help solidify your understanding of this hour’s lesson, you are encouraged to answer the quiz questions and finish the exercises provided in the workshop before you move to the next lesson. The answers and hints to the questions and exercises are given in Appendix B, “Answers to Quiz Questions and Exercises.”
Quiz
1. How can you obtain the left value of a character variable ch?
2. In the following expressions, which asterisk (*) is a dereference operator, and which one is a multiplication operator?
• *ptr
• x * y
• y *= x + 5
• *y *= *x + 5
3. Given that x = 10, the address of x is 0x1A38, and ptr_int = &x, what will ptr_int and *ptr_int produce, respectively?
4. Given that x = 123, and ptr_int = &x after the execution of *ptr_int = 456, what does x contain?
Exercises
1. Given three integer variables, x = 512, y = 1024, and z = 2048, write a program to print out their left values as well as their right values.
2. Write a program to update the value of the double variable flt_num from 123.45
to 543.21 by using a double pointer.
3. Given a character variable ch and ch = ‘A’, write a program to update the value of ch to decimal 66 by using a pointer.
4. Given that x=5 and y=6, write a program to calculate the multiplication of the two integers and print out the result, which is saved in x, all in the way of indirection (that is, using pointers).
16 067231861x CH12 1/25/00 10:18 AM Page 189
HOUR 12
Understanding Arrays
Gather up the fragments that remain, that nothing be lost.
—John 6:12
In last hour’s lesson you learned about pointers and the concept of indirection. In this lesson you’ll learn about arrays, which are collections of similar data items and are closely related to pointers. The main topics covered in this lesson are
• Single-dimension arrays
• Indexing arrays
• Pointers and arrays
• Character arrays
• Multidimensional arrays
• Unsized arrays
16 067231861x CH12 1/25/00 10:18 AM Page 190
190
Hour 12
What Is an Array?
You now know how to declare a variable with a specified data type, such as char, int, float, or double. In many cases, you have to declare a set of variables that have the same data type. Instead of declaring them individually, C allows you to declare a set of variables of the same data type collectively as an array.
An
array
is a collection of variables that are of the same data type. Each item in an array is called an
element
. All elements in an array are referenced by the name of the array and are stored in a set of consecutive, adjacent memory slots.
Declaring Arrays
The following is the general form to declare an array:
data-type Array-Name[Array-Size];
Here data-type is the type specifier that indicates what data type the declared array will be. Array-Name is the name of the declared array. Array-Size defines how many elements the array can contain. Note that the brackets ([ and ]) are required in declaring an array. The bracket pair ([ and ]) is also called the
array subscript operator
.