CSCI-1200 Data Structures - Fall 2009 Lecture 5 - Pointers, Arrays, Pointer Arithmetic
CSCI-1200 Data Structures - Fall 2009 Lecture 5 - Pointers, Arrays, Pointer Arithmetic
• Closed-book and closed-notes except for 1 sheet of notes on 8.5x11 inch paper (front & back) that may be
handwritten or printed. Computers, cell-phones, palm pilots, calculators, PDAs, music players, etc. are not
permitted and must be turned off.
• Practice problems from previous exams will be available on the course website. Solutions to the problems will
be posted later.
• They can be used to access the values stored at their stored memory address.
• Pointers are also the primitive mechanism underlying vector iterators, which we have used with std::sort and
will use more extensively throughout the semester.
float x = 15.5;
float *p; /* equiv: float* p; */ 72.0
x 15.5 x
p = &x;
*p = 72;
if ( x > 20 )
cout << "Bigger\n";
else
cout << "Smaller\n"; p p
• There is no initialization of pointer variables in this two-line sequence, so a statement below is dangerous, and
may cause your program to crash! (It won’t crash if the uninitialized value happens to be a legal address.)
*p = 15;
• Assignments of integers or floats to pointers and assignments mixing pointers of different types are illegal.
Continuing with the above example:
int *r;
r = q; // Illegal: different pointer types;
p = 35.1; // Illegal: float assigned to a pointer
5.5 Exercise
• What is the output of the following code sequence?
int x = 10, y = 15;
int *a = &x;
cout << x << " " << y << endl;
int *b = &y;
*a = x * *b;
cout << x << " " << y << endl;
int *c = b;
*c = 25;
cout << x << " " << y << endl;
2
5.6 Null Pointers
• Pointers that don’t (yet) point anywhere useful should be explicitly assigned the value 0, a legal pointer value.
– Most compilers define NULL to be a special pointer equal to 0.
• Comparing a pointer to NULL is very useful. It can be used to indicate whether or not a pointer has a
legal address. (But don’t make the mistake of assuming pointers are automatically initialized to NULL.) For
example,
if ( p != NULL )
cout << *p << endl.
tests to see if p is pointing somewhere that appears to be useful before accessing the value stored at that
location.
• Dereferencing a null pointer leads to memory exceptions (program crashes).
5.7 Arrays
• Here’s a quick example to remind you about how to use an array:
• Remember: the size of array a is fixed at compile time. STL vectors act like arrays, but they can grow and
shrink dynamically in response to the demands of the application.
• The assignment: p = a; takes the address of the start of the array and assigns it to p.
• This illustrates the important fact that the name of an array is in fact a pointer to the start of a block of
memory. We will come back to this several times! We could also write this line as:
p = &a[0];
which means “find the location of a[0] and take its address”.
• The test p<a+n checks to see if the value of the pointer (the address) is less than n array locations beyond the
start of the array. We could also have used the test p != a+n
• By incrementing, ++p, we make p point to the next location in the array.
• In the assignment:
*p = sqrt( p-a )
p-a is the number of array locations between p and the start. This is an integer. The square root of this value
is assigned to *p.
• We will draw a picture of this in class.
3
5.9 Sorting an Array
• Arrays may be sorted using std::sort, just as vectors may. Pointers are used in place of iterators. For
example, if a is an array of doubles and there are n values in the array, then here’s how to sort the values in
the array into increasing order:
std::sort( a, a+n )
5.10 Exercises
For each of the following problems, you may only use pointers and not subscripting:
1. Write code to print the array a backwards, using pointers.
2. Write code to print every other value of the array a, again using pointers.
3. Write a function that checks whether the contents of an array of doubles are sorted into increasing order. The
function must accept two arguments: a pointer (to the start of the array), and an integer indicating the size of
the array.
• A char array can be initialized as: char h[] = {’H’, ’e’, ’l’, ’l’, ’o’, ’!’, ’\0’};
or as: char h[] = "Hello!";
In either case, array h has 7 characters, the last one being the null character.
• The C and C++ languages have many functions for manipulating these “C-style strings”. We don’t study
them much anymore because the standard string library is much more logical and easier to use.
• One place we do use them is in file names and command-line arguments, as you have already seen.
4
5.13 C Calling Convention
• A calling convention is a standardized method for passing arguments between the caller and the function.
Calling conventions vary between programming languages, compilers, and computer hardware.
• In C on x86 architectures here is a generalization of what happens:
1. The caller puts all the arguments on the stack, in reverse order.
2. The caller puts the address of its code on the stack (the return address).
3. Control is transferred to the callee.
4. The callee puts any local variables on the stack.
5. The callee does its work and puts the return value in a special register (storage location).
6. The callee removes its local variables from the stack.
7. Control is transferred by removing the address of the caller from the stack and going there.
8. The caller removes the arguments from the stack.
• On x86 architectures the addresses on the stack are in descending order. This is not true of all hardware.
int main() {
int x = 5;
int y = 7;
int answer = foo (x, &y);
cout << "address of x = " << &x << endl;
cout << "address of y = " << &y << endl; 0x23ef18
cout << "address of answer = " << &answer << endl; x= 0x23ef14 5
cout << "value at " << &x << " = " << x << endl;
cout << "value at " << &y << " = " << y << endl; y= 0x23ef10 7
cout << "value at " << &answer << " = " << answer << endl; answer= 0x23ef0c 48
}
0x23ef08
Sample Output 0x23ef04
address of a = 0x23eef0 0x23ef00
address of b = 0x23eef4 0x23eefc
address of q = 0x23eee4
address of r = 0x23eee0
0x23eef8
value at 0x23eef0 = 5 b= 0x23eef4 0x23ef10
value at 0x23eef4 = 0x23ef10
value at 0x23ef10 = 7
a= 0x23eef0 5
value at 0x23eee4 = 6 0x23eeec
value at 0x23eee0 = 8 0x23eee8
address of x = 0x23ef14
address of y = 0x23ef10 q= 0x23eee4 6
address of answer = 0x23ef0c r= 0x23eee0 8
value at 0x23ef14 = 5
value at 0x23ef10 = 7 0x23eedc
value at 0x23ef0c = 48 0x23eed8