Programming in C Pointer Basics 72809 Why Pointers
Programming in C Pointer Basics 7/28/09
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. 7/28/09
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/28/09
Java Reference vs. C Pointers • In Java, a reference variable is used to give a name to an object. The reference variable contains the memory address at which the object is stored. Truck ford = new Truck( ); • Since C does not support objects, it does not provide reference variables. However, C provides pointer variables which contain the memory address of another variable (sometimes called the “pointee”). A pointer may point to any kind of variable. 7/28/09
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 *name. Of. Pointer; 7/28/09
Pointer Declaration The declaration int *int. Ptr; defines the variable int. Ptr to be a pointer to a variable of type int. Ptr will contain the memory address of some int variable. Read this declaration as – “int. Ptr is a pointer to an int”, or equivalently – “*int. Ptr is an int” Caution -- Be careful when defining multiple variables on the same line. In this definition int *int. Ptr, int. Ptr 2; int. Ptr 2 int. Ptr is a pointer to an int, but int. Ptr 2 is not! 7/28/09
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 variable to which the pointer points. – The & operator gives the address of a variable. Recall the use of & in scanf( ) 7/28/09
Pointer Examples int x = 1, y = 2, z[10]; int *ip; /* ip is a pointer to an int */ ip = &x; y = *ip; *ip = 0; ip = &z[5]; /* /* ip points to (contains the memory address of) x */ y is now 1, indirectly copied from x using ip */ x is now 0 */ ip now points to z[5] */ If ip points to x, then *ip can be used anywhere x can be used so *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. ) 7/28/09
NULL • NULL is a special value which may be assigned to a pointer • NULL indicates that this pointer does not point to any variable • Often used when pointers are declared int *p. Int = NULL; • Often used as the return type of functions that return a pointer to indicate function failure int *my. Ptr = my. Function( ); if (my. Ptr == NULL) /* something bad happened */ • Dereferencing a pointer whose value is NULL will result in program termination. 7/28/09
Pointers and Function Arguments Since C passes all 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. It only swaps the copies of x and y; /* 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; } 7/28/09
A better swap( ) The desired effect can be obtained by passing pointers to the values to be exchanged. /* 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; } 7/28/09
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 by the function. 7/28/09
convert. Time. c void convert. Time (int time, int *p. Hours, int *p. Mins) { *p. Hours = time / 60; *p. Mins = time % 60; } int main() { int time, hours, minutes; printf("Enter a time duration in minutes: "); scanf ("%d", &time); convert. Time (time, &hours, &minutes); printf("HH: MM format: %d: %02 dn", hours, minutes); return 0; } 7/28/09
Pointers to struct /* define a struct for related student data */ ypedef 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 *p. Student; /* p. Student is a "pointer to struct student" */ /* make p. Student point to bob */ p. Student = &bob; /* use -> to access the members */ printf ("Bob's name: %sn", p. Student->name); printf ("Bob's gpa : %fn", p. Student->gpa); /* make p. Student point to sally */ p. Student = &sally; printf ("Sally's name: %sn", p. Student->name); printf ("Sally's gpa: %fn", p. Student->gpa); Note too that the following are equivalent. Why? ? p. Student->gpa and (*p. Student). gpa /* the parentheses are necessary */ 7/28/09
Pointers in a struct The data member of a struct can be any data type, including pointer. The person struct now has a pointer to the name struct. typedef struct name { char first[ 51 ]; char last [ 51 ]; } NAME; typedef struct person { struct name *p. Name; int age; float gpa; } PERSON; Given the declarations below, how do we access bob’s name, last name, and first name? Draw a picture of memory represented by these declarations NAME bobs. Name = {“Bob”, “Smith”}; PERSON bob; bob. age = 42; bob. gpa = 3. 4; bob. p. Name = &bobs. Name; 7/28/09
Self-referencing structs • Powerful data structures can be created when a data member of a struct is a pointer to a struct of the same kind. • The simple example on the next slide illustrates the technique. • More important uses of this technique will be seen later. 7/28/09
teammates. c typedef struct player { char *name; struct player *teammate; } TEAMMATE; /* can’t use TEAMMATE yet */ TEAMMATE *team, bob, harry, john; team = &bob; /* first player on the team */ bob. name = “bob”; bob. teammate = &harry; /* next teammate */ harry. name = “harry”; harry. teammate = &john; /* next teammate */ john. name = “bill”; john. teammate = NULL: /* last teammate */ TEAMMATE *t = team; while (t != NULL) { printf(“%sn”, t->name); t = t->teammate; } 7/28/09 /* print the teammates by following*/ /* the teammate pointers until */ /* there are no more teammates */
End of Class 4 7/28/09
- Slides: 18