# Pointers and Pointer Arithmetic

Dr. Lawlor, CS 202, CS, UAF

So you've got an array:
`	int arr;`
You can access the elements of the array using array indexing, like "arr".  You can also point to a given array element using the address-of operator:
`	int arr;	arr=0; arr=1; arr=20; arr=300;	int *p=&arr; /* point to arr */	*p=999;	for (int i=0;i<4;i++) cout<<"arr["<<i<<"]="<<arr[i]<<"\n";`

(Try this in NetRun now!)

The pointer is accessing arr, so this prints:
`arr=0arr=1arr=999arr=300`
You can move the pointer p down so it points to arr with:
`	p++;`
(Try this in NetRun now!)

This does the same thing as saying:
`	p=p+1;`

You can even move the pointer backwards, pointing to arr:

`	int arr;	arr=0; arr=1; arr=20; arr=300;	int *p=&arr; /* point to arr */	p=p-1; /* move from arr to arr */	*p=999;	for (int i=0;i<4;i++) cout<<"arr["<<i<<"]="<<arr[i]<<"\n";`

(Try this in NetRun now!)

This prints

`arr=0arr=999arr=20arr=300`

In fact, normal array indexing can be written using pointer arithmetic.  We treat the array as a pointer, move down by "i" integers, and access the data there:

`	arr[i]=999;	*(arr+i)=999;`
In fact, because addition is commutative, this is exactly the same as:
`	*(i+arr)=999;	i[arr]=999;`
This works fine, but of course it looks extremely weird!  (Try this in NetRun now!)

In general, all of the following operations work fine on pointers:

• p=&i; make a pointer point at the integer i.
• p++; move the pointer forward in memory, so it points to the next value.
• p=0; make the pointer point to the (invalid) memory at address zero.
• *p=0; make the pointed-to value equal zero.
• *p++=0; make the pointed-to value equal zero, then move the pointer forwards.
• p--; move the pointer backward in memory, so it points to the previous value.
• p=p+i; move the pointer forward by i spaces.
• p=p-i; move the pointer backward by i spaces.
• cout<<p;  print the pointer itself, a weird hexadecimal value like 0x7fffffffe648.
• cout<<*p; print the thing the pointer is pointing at (dereference and print).
• cout<<*p++; print the thing the pointer is pointing at, then move the pointer forwards (dereference, print, and increment).
• if (p==q) ...: compare two pointers, to see if they're pointing at the same place in memory.
• if (*p==*q) ...: compare the values two pointers are pointing at, to see if they're pointing to equal values.
• if (p!=q) ...: compare if two pointers are pointing at different places in memory.
Real C++ programs often combine these features.  For example, here's a program that loops over the characters in a string, by pointing to the first character, moving the pointer to each subsequent character, and continuing until we're pointing to an 'X' character:
`const char *arr="howdyX";for (const char *p=arr;*p!='X';p++)	cout<<*p<<"\n";`

(Try this in NetRun now!)

The more typical way to write this loop would be to continue the loop until we hit the 0 character (ASCII nul byte) at the end of the string:
`const char *arr="howdy";for (const char *p=arr;*p!=0;p++)	cout<<*p<<"\n";`

(Try this in NetRun now!)

Here's a program that loops over the elements of an integer array using a pointer.  Each time through the loop, "p++" advances the pointer to the next element.  The loop test, "p!=end", compares our pointer to "end", which points to the end of the array.
`int arr;arr=0; arr=1; arr=20; arr=300;int *end=&arr; // one-past-last element of arrayfor (int *p=&arr;p!=end;p++)	cout<<"memory at "<<p<<" = "<<*p<<"\n";`