2. What is a pointer
• In a generic sense, a “pointer” is anything that tells us
where something can be found.
– Addresses in the phone book
– URLs for webpages
– Road signs
3. Java Reference
• In Java, the name of an object is a reference to that object.
Here ford is a reference to a Truck object. It contains the
memory address at which the Truck object is stored.
Truck ford = new Truck( );
• The syntax for using the reference is pretty simple. Just
use the “dot” notation.
ford.start( );
ford.drive( 23 );
ford.turn (LEFT);
4. What is a pointer ?
• In C, a pointer variable (or just “pointer”) is similar to
a reference in Java except that
– A pointer can contain the memory address of any variable
type (Java references only refer to objects)
– A primitive (int, char, float)
– An array
– A struct or union
– Dynamically allocated memory
– Another pointer
– A function
– There’s a lot of syntax required to create and use pointers
5. Why Pointers?
• They allow you to refer to large data structures in a compact
way
• They facilitate sharing between different parts of programs
• They make it possible to get new memory dynamically as your
program is running
• They make it easy to represent relationships among data items.
6. Pointer Caution
• They are a powerful low-level device.
• Undisciplined use can be confusing and thus the
source of subtle, hard-to-find bugs.
– Program crashes
– Memory leaks
– Unpredictable results
7. C Pointer Variables
To declare a pointer variable, we must do two things
– Use the “*” (star) character to indicate that the variable being
defined is a pointer type.
– Indicate the type of variable to which the pointer will point (the
pointee). This is necessary because C provides operations
on pointers (e.g., *, ++, etc) whose meaning depends on the
type of the pointee.
• General declaration of a pointer
type *nameOfPointer;
8. Pointer Declaration
The declaration
int *intPtr;
defines the variable intPtr to be a pointer to a variable of type
int. intPtr will contain the memory address of some int
variable or int array. Read this declaration as
– “intPtr is a pointer to an int”, or equivalently
– “*intPtr is an int”
Caution -- Be careful when defining multiple variables on the same
line. In this definition
int *intPtr, intPtr2;
intPtr is a pointer to an int, but intPtr2 is not!
9. Pointer Operators
The two primary operators used with pointers are
* (star) and & (ampersand)
– The * operator is used to define pointer variables and to
deference a pointer. “Dereferencing” a pointer means to use
the value of the pointee.
– The & operator gives the address of a variable.
Recall the use of & in scanf( )
10. Pointer Examples
int x = 1, y = 2, z[10];
int *ip; /* ip is a pointer to an int */
ip = &x; /* ip points to (contains the memory address of) x */
y = *ip; /* y is now 1, indirectly copied from x using ip */
*ip = 0; /* x is now 0 */
ip = &z[5]; /* ip now points to z[5] */
If ip points to x, then *ip can be used anywhere x can be used so in this
example *ip = *ip + 10; and x = x + 10; are equivalent
The * and & operators bind more tightly than arithmetic operators so
y = *ip + 1; takes the value of the variable to which ip points, adds 1
and assigns it to y
Similarly, the statements *ip += 1; and ++*ip; and (*ip)++; all increment
the variable to which ip points. (Note that the parenthesis are
necessary in the last statement; without them, the expression would
increment ip rather than what it points to since operators like * and
++ associate from right to left.)
11. Pointer and Variable types
• The type of a pointer and its pointee must match
int a = 42;
int *ip;
double d = 6.34;
double *dp;
ip = &a; /* ok -- types match */
dp = &d; /* ok */
ip = &d; /* compiler error -- type mismatch */
dp = &a; /* compiler error */
12. More Pointer Code
• Use ampersand ( & ) to obtain the address of the pointee
• Use star ( * ) to get / change the value of the pointee
• Use %p to print the value of a pointer with printf( )
• What is the output from this code?
int a = 1, *ptr1;
/* show value and address of a
** and value of the pointer */
ptr1 = &a ;
printf("a = %d, &a = %p, ptr1 = %p, *ptr1 = %dn",
a, &a, ptr1, *ptr1) ;
/* change the value of a by dereferencing ptr1
** then print again */
*ptr1 = 35 ;
printf(“a = %d, &a = %p, ptr1 = %p, *ptr1 = %dn", a,
&a, ptr1, *ptr1) ;
13. NULL
• NULL is a special value which may be assigned to a pointer
• NULL indicates that this pointer does not point to any variable
(there is no pointee)
• Often used when pointers are declared
int *pInt = NULL;
• Often used as the return type of functions that return a pointer to
indicate function failure
int *myPtr;
myPtr = myFunction( );
if (myPtr == NULL){
/* something bad happened */
}
• Dereferencing a pointer whose value is NULL will result in
program termination.
14. Pointers and Function Arguments
• Since C passes all primitive function arguments “by value” there
is no direct way for a function to alter a variable in the calling
code.
• This version of the swap function doesn’t work. WHY NOT?
/* calling swap from somewhere in main() */
int x = 42, y = 17;
Swap( x, y );
/* wrong version of swap */
void Swap (int a, int b)
{
int temp;
temp = a;
a = b;
b = temp;
}
15. A better swap( )
• The desired effect can be obtained by passing pointers to the
values to be exchanged.
• This is a very common use of pointers.
/* calling swap from somewhere in main( ) */
int x = 42, y = 17;
Swap( &x, &y );
/* correct version of swap */
void Swap (int *px, int *py)
{
int temp;
temp = *px;
*px = *py;
*py = temp;
}
16. More Pointer Function
Parameters
• Passing the address of variable(s) to a function can
be used to have a function “return” multiple values.
• The pointer arguments point to variables in the calling
code which are changed (“returned”) by the function.
17. ConvertTime.c
void ConvertTime (int time, int *pHours, int *pMins)
{
*pHours = time / 60;
*pMins = time % 60;
}
int main( )
{
int time, hours, minutes;
printf("Enter a time duration in minutes: ");
scanf ("%d", &time);
ConvertTime (time, &hours, &minutes);
printf("HH:MM format: %d:%02dn", hours, minutes);
return 0;
}
18. An Exercise
• What is the output from this code?
void F (int a, int *b)
{
a = 7 ;
*b = a ;
b = &a ;
*b = 4 ;
printf("%d, %dn", a, *b) ;
}
int main()
{
int m = 3, n = 5;
F(m, &n) ;
printf("%d, %dn", m, n) ;
return 0;
}
4, 4
3, 7
19. Pointers to struct
/* define a struct for related student data */
typedef struct student {
char name[50];
char major [20];
double gpa;
} STUDENT;
STUDENT bob = {"Bob Smith", "Math", 3.77};
STUDENT sally = {"Sally", "CSEE", 4.0};
STUDENT *pStudent; /* pStudent is a "pointer to struct student" */
/* make pStudent point to bob */
pStudent = &bob;
/* use -> to access the members */
printf ("Bob's name: %sn", pStudent->name);
printf ("Bob's gpa : %fn", pStudent->gpa);
/* make pStudent point to sally */
pStudent = &sally;
printf ("Sally's name: %sn", pStudent->name);
printf ("Sally's gpa: %fn", pStudent->gpa);
Note too that the following are equivalent. Why??
pStudent->gpa and (*pStudent).gpa /* the parentheses are necessary */
20. Pointer to struct for functions
void PrintStudent(STUDENT *studentp)
{
printf(“Name : %sn”, studentp->name);
printf(“Major: %sn”, studentp->major);
printf(“GPA : %4.2f”, studentp->gpa);
}
Passing a pointer to a struct to a function is more
efficient than passing the struct itself. Why is this
true?