Chapter 6 Pointers and Arrays

Ø  This chapter addresses the following two issues:

1.  How to access a variable (memory location) using its address.

2.  How to process a collection of data as a list or a table.

Ø  If you want to use the address of a variable (memory location) to access it, you must first define a variable called pointer variable to hold that address.

Ø  A list of data is processed in the C++ language by using a one-dimensional array, and a table of data is processed by using a two-dimensional array.


6.1 Pointer Variables

Ø  A pointer variable is a variable that you define to hold the address of another variable (memory location).

Ø  You define a pointer variable as follows: data-type> * <pointer-variable> ;

Ø  C++ distinguishes a pointer variable to hold the address of an integer variable from the one to hold the address of an integer variable, or a floating point variable.

Ø  <data-type> specifies the data type of the variables whose addresses may be held in the pointer variable.


Figure 6.1

Defining Pointer variables

a)

char * cpt; /* cpt is a pointer variable to hold the address of a character (char) variable */

int * ipt; /* ipt is a pointer variable to hold the address of an integer (int) variable */

double * dpt; /* dpt is a pointer variable to hold the address of a double precision floating point (double) variable */

b)  You may define pointer variables with other variables in the same declaration statement as follows:

int num = 10, * ipt1, result;

int *ipt1, num = 10, *ipt2, result;


Figure 6.2

Storing an Address into a Pointer Variable

©2010 Gilbert Ndjatou Page 4

Given the following definitions of variables with their memory representations:

Memory Locations

Address Address

int *iptr; 103 iptr 135 ivar

int ivar = 10, *iptrl;

double dvar = 7.5, *dptr; 206 iptr1 231 dvar

char cvar = ‘Z’, *cptr;

275 dptr 283 cvar

298 cptr

The following assignment statements are valid and have the specified effects on the memory locations:

Memory Locations

Address Address

iptr = &ivar; 103 iptr 135 ivar

dptr = &dvar;

cptr = &cvar; 206 iptr1 231 dvar

iptr1 = iptr;

275 dptr 283 cvar

298 cptr

Ø  A pointer variable that holds the address of another variable is used to access that variable (memory location) by preceding it with the indirection or deference operator (*)

Figure 6.3

Using a pointer variable to access the current value of a memory location

Given the definitions of variables and the assignment statements figure 6.2, each of the following statements will produce the specified output:

Statements Output

a) cout < endl < “*iptr + 5 = \t” < (*iptr + 5); *iptr + 5 = 15

b) cout < endl < “*cptr = \t” < *cptr; *cptr = Z

c) cout < endl < “*dptr * 3 = \t” < (*dptr * 3); *dptr * 3 = 22.5

·  The expression (*iptr + 5) is read: “get the value in the memory location ( of the variable) at the address in pointer variable iptr, and add 5 to it.”

·  The expression *cptr is read: “get the value in the memory location (of the variable) at the address in pointer variable cptr.”

·  The expression (*dptr * 3) is read: “get the value in the memory location ( of the variable) at the address in pointer variable dptr and multiply it by 3.”

Ø  A pointer variable that holds the address of another variable (memory location) may also be used to store a value into that variable (memory location).

Figure 6.4

Using a pointer variable to store a value into a memory location

Given the definitions of variables and the assignment statements in section 2, the following program segment will produce the specified output:

* cptr = ‘X’;

* dptr = dvar + 3;

* iptr = * iptr + 8;

cout < “\ncvar =\t” < cvar < “\nivar =\t” < ivar;

cout < endl < “dvar =\t” < dvar;

Output

cvar = X

ivar = 18

dvar = 10.5

·  The assignment statement * cptr = ‘X’; says to store character ‘X’ in the memory location at the address in pointer variable cptr;

·  the assignment statement * dptr = dvar + 3; says to add the current value of variable dvar to 3 and to store the result in the memory location at the address in pointer variable dptr;

·  The assignment statement * iptr = * iptr + 8; says to get the current value in the memory location at the address in pointer variable iptr, add 8 to it, and to store the result in the memory location at the address in pointer variable iptr.

©2010 Gilbert Ndjatou Page 6


Practice Exercise 6.1

Show the output of the following code segment

int *pt1, *pt2, num1= 10, num2 = 5, num3;

pt1 = &num1;

*pt1 = 20;

pt2 = &num2;

num3 = *pt2 + 7;

num2 += 4;

cout < endl < “num1=” < num1 < endl < “num2=” < num2 < endl < “num3=” < num3;

< endl < “*pt1=” < *pt1 < endl < “*pt2=” < *pt2;

Homework Exercise 6.2

Show the output of each of the following code segments:

a. int num1 = 20, *numptr1, *numptr2, num2 = 0;

numptr1 = &num1;

numptr2 = &num2;

*numptr2 = 5;

cout < "\n num1 = “ < num1 < “\n*numptr1 = " < *numptr1;

cout < "\n num2 = “ < num2 < “\n*numptr2 = " < *numptr2;

cout < “\n*numptr1 + 8=\t” < (*numptr1 + 8);

b. int num1 = 20, *numptr1, *numptr2, num2 = 0;

numptr1 = &num1;

numptr2 = numptr1;

*numptr2 = 27;

cout < "\n num1 = “ < num1 < “\n*numptr1 = " < *numptr1;

cout < "\n num2 = “ < num2 < “\n*numptr2 = " < *numptr2;

c. int num1 = 20, *numptr1, *numptr2, num2 = 0;

numptr1 = &num1;

numptr2 = &num2;

num1 = 12;

*numptr2 = *numptr1 + 6;

cout < "\n num1 = “ < num1 < “\n*numptr1 = " < *numptr1;

cout < "\n num2 = “ < num2 < “\n*numptr2 = " < *numptr2;

6.2  Pointer Parameters

Ø  In C++, a function can use the address of a variable (memory location) to have access to that variable in the calling function.

Ø  A function that receives an address (when it is called) must have a pointer parameter that is initialized with that address when the function is called.

Ø  We have the following correspondence between pointer parameters and the addresses that may be passed to the function:

Pointer Parameter Address of:

Character pointer character variables

Integer pointer integer variables

Single precision floating point pointer single precision floating point variables

Double precision floating point pointer double precision floating point variables

Ø  The following example illustrates the use of pointer parameters:

©2010 Gilbert Ndjatou Page 9

Given the following definitions of functions tester and main:

void tester ( int num, int * pt)

{

* pt = * pt + num;

}

int main()

{

int tvalue = 5;

tester ( 7, & tvalue);

cout < endl < “tvalue = \t” < tvalue;

return 0;

}

After the call statement: tester ( 7, & tvalue);

The body of function tester is executed as if it was written as follows:

{

num = 7;

pt = &tvalue;

* pt = * pt + num;

}

So the output of the program is:

Output

tvalue = 12

Ø  Note that using pointer parameters is very similar to using reference parameters, except that with a pointer parameter, a value (which is an address) is passed to the function, whereas with reference parameters, no value is actually passed to the function.


Practice Exercise 6.3

Show the body of the function tester in the way that it is executed after the function call. Then execute the program and show its output.

void tester ( int num, int * pt)

{

* pt = * pt - num;

}

int main()

{

int tvalue = 20;

tester ( 4, & tvalue);

cout < endl < “tvalue = \t” < tvalue;

return 0;

}

Homework Exercise 6.4

Show the body of the function tester in the way it is executed after the function call. Then execute the program and show its output.

void tester(int num, int *p1, int *p2)

{

num = num + 5;

*p1 = *p1 + 5;

*p2 = num ;

}

int main()

{

int i = 10, j, k, *ptr;

j = 15;

ptr = &j;

tester(i, ptr, &k);

cout < “\ni =\t” < i < “\nj =\t” < j

< “\nk =\t” < k;

return(0);

}

6.3  One-Dimensional Arrays

Ø  The solutions of some problems are possible only if the data to be processed are stored in the main memory, and are processed as a list.

Consider the problem of reading the test scores of 20 students, computing their average, and finding out how many students have a test score above the average.

Ø  After the average test score is computed, each test score must be compared to it in order to find out how many students have a test score above the average.

Ø  We must therefore be able to hold all 20 test scores inside the main memory, so that we can compare each one to the average after it has been computed.

Ø  One way to hold 20 test scores in memory is to use 20 double precision variables. But this approach is not practical because this class could as well have 50 or even 100 students.

Ø  Another way is to use a one-dimensional array that we will discuss in the following section.


Defining and Referencing One-Dimensional Arrays

Ø  You define a one-dimensional array by using the following declaration statement:

<data-type> <array-name> [ size ];

<array-name> is the name of the array or the list,

<data-type> is the data type of the variables in the list, and

size is the number of variables in the list.

Examples of one-dimensional array definitions:

char letter[5]; /*list of 5 variables to hold character values */

int idlist[5]; /* list of 5 variables to hold integer values */

double scores[10]; /*list of 10 variables to hold double precision floating point values */


Array Element – Indexed Variable

Ø  When you define an array A of size n, you are creating a list a variables

A[0], A[1], A[2], . . . , and A[n-1].

called:

o  indexed variables or

o  array elements

char letter[5]; will create the following indexed variables:

letter[0], letter[1], letter[2], letter[3], and letter[4].

int idList[ 5 ]; will create the following indexed variables:

idlist[0], idlist[1], idlist[2], idlist[3], and idlist[4].

double scores[ 10 ]; will create the following indexed variables:

scores[0], scores[1], scores[2], scores[3], . . . , and scores[9].

Practice Exercise 6.5

Write the declaration statements to define the following arrays:

  1. Array scoreList of 20 double precision floating point elements.
  2. Array line to hold 80 characters
  3. Array valueList to hold 50 integer values.


Indexed Variables and Memory Locations

Ø  Contiguous memory locations are allocated for the indexed variables of an array and

Ø  The name of an array is a pointer constant that holds the address of the first element of the array.

Figure 6.5 Indexed Variables and Memory Locations

The indexed variables of the following two arrays are represented in memory as follows:

char letters[5];

int idlist[5];

Memory

letters

Addresses: 2000 2001 2002 2003 2004

letters[0] letters[1] letters[2] letters[3] letters[4]

idlist

Addresses: 2300 2304 2308 2312 2316

idlist[0] idlist[1] idlist[2] idlist[3] idlist[4]

©2010 Gilbert Ndjatou Page 15

Ø  Note that a character variable occupies a byte of memory location whereas an integer value occupies a four-byte memory location in an Intel Pentium computer.


Practice Exercise 6.6

Write the declaration statement to define each of the following arrays and also show their memory representations (make up memory addresses if they are needed).

  1. Array letters of 8 characters.
  2. Array numberList of 5 integer values.


Initializing the Elements of a One-Dimensional Array

Ø  You can initialize the elements of a one-dimensional array only when it is defined.

Ø  You initialize a one-dimensional array by following its definition with the assignment operator, which is followed by the list of initial values enclosed between the left and the right braces.

·  The first value in the list is assigned to the first element of the array,

·  the second value to the second element, . . . , etc.

·  If there are not enough values for all the elements of the array, the rest of the elements are initialized to 0 (for numeric values) and the null character (for characters).


Figure 6.6 Initializing Arrays

1. int values[5] = { 10, 20, 30, 40, 50 }; assigns the values as follows:

10 / 20 / 30 / 40 / 50

values[0] values[1] values[2] values[3] values[4]

2. int values[5] = {10, 20, 30 }; assigns the values as follows:

10 / 20 / 30 / 0 / 0

values[0] values[1] values[2] values[3] values[4]

3. char letters[5] = { ‘A’, ‘B’}; assigns the values as follows:

‘A’ / ‘B’ / ‘\0’ / ‘\0’ / ‘\0’

letters[0] letters[1] letters[2] letters[3] letters[4]

4. int values[ ] = {10, 20, 30, 40}; assigns the values as follows:

10 / 20 / 30 / 40

values[0] values[1] values[2] values[3]

Ø  You do not have to specify the size of an array in the declaration statement when it is initialized:

The number of elements will be exactly the same as the number of initial values provided in the list of values.

Ø  An array of characters may also be initialized with a string constant when it is defined in one of the following ways:

char <array-name> [size] = <string-constant>;

or

char <array-name> [size] = { <string-constant> };

Ø  The characters of the string constant are stored into the elements of the array, including a Null character at the end.

Figure 6.7

1. char name[6] = { “John” }; assigns the values as follows: