Introduction to C / C++ Programming
Pointers

Addresses, the Address Operator, and printing Addresses

			int i = 42;
			printf( "The variable i has value %d, and is located at 0x%p\n", i, &i );

might produce the following result:

			The variable i has value 42, and is located at 0x0022FF44

Pointer Variables

Declaring Pointer Variables

	int i, j, *iptr, k, *numPtr, *next;

variables i, j,and k are of type ( int ), and variables iptr, numPtr, and next are of type ( pointer to int ). Note that regular ints and int pointers can be mixed on a single declaration line.

void Pointers

Initializing Pointer Variables

NULL Pointers

	double d, *dptr = NULL, e;

Assigning Pointer Variables

Using Pointer Variables - The Indirection Operator

int i, , j;
int *iptr = &i, *jptr = &j;     // These * indicates variables of type ( pointer to int )

i = 42;          // changes i to 42
*iptr = 100;     // changes i from 42 to 100
j = *iptr;       // Now j is 100 also

// Note carefully the distinction between the following two lines:

*jptr = *iptr;  // Equivalent to j = i. jptr and iptr still point to different places
jptr = iptr;    // Makes jptr point to the same location as iptr.  Both now point to i

  

Pointers and Functions

Pointers as Function Arguments - Pass by Pointer / Address

void func( int a, int *bptr ) {

	a = 42;
	*bptr = 42;
	return;
}

int main( void ) {

	int x = 100, y = 100;

	func( x, &y );

	printf( "x = %d, y = %d\n", x, y );

	return 0;
}

Preventing Changes with const

	double func( const int *ptr );
	double func(  int * const ptr );
	double func( const int * const ptr );
 

Returning Addresses from Functions

Pointers to Functions

Pointers and Arrays

Pointers to Array Elements

	int nums[ 10 ], iptr = NULL;

	iptr = & nums[ 3 ];		// iptr now points to the fourth element

	*iptr = 42;				// Same as nums[ 3 ] = 42;

Pointer Arithmetic

Interchangeability of Pointers and Arrays

Because of the pointer arithmetic works, and knowing that the name of an array used without subscripts is actually the address where the beginning of the arrays is located, and assuming the following declarations:

int nums[ 10 ], *iptr = nums;

Then the following statements are equivalent:

What may come as more of a surprise is that the following two statements are also legal, and equivalent to the first two:

Basically since nums and iptr are both addresses of where ints are stored, the computer treats them identically when interpreting the array element operator, [ ], and the dereference operator, *. ( The compiler will generate the exact same machine instructions for all four of the lines given above. ) The only difference is that nums is a fixed address determined by the compiler, that cannot be changed while the program is running, whereas iptr is a variable, that can be changed to point to other locations. ( iptr refers to a memory location on the stack that holds an address,whereas nums is a constant inserted into the instructions. )

Looping Through Arrays Using Pointers

The following code will print the characters in the array passed to the function, until a null byte is found, and will then print a new line character. ( It will make more sense after character arrays are covered. )

    
		void printString( const char array[ ] ) { // Same as printString( const char * array )

			char *p = array;

			while( *p )
				printf( "%c", *p++ );
			printf( "\n" );

			return;
		}

Combinations of * and ++

Pointers and Multidimensional Arrays

Given the declaration:

int matrix[ NROWS ][ NCOLS ], * iptr = matrix;

then the following are also equivalent:

This is why functions receiving two-dimensional arrays as input need to know how many columns are in the array, but don't care how many rows are present.

Arrays of Pointers

Arrays can hold any data type, including pointers. So the declaration:

int * ipointers[ 10 ];

would create an array of 10 pointers, each of which points to an int.

Pointers and Structs