180 likes | 207 Views
Learn why pointers are important in C programming. Explore how pointers allow for efficient data handling and memory management. Discover the differences between Java references and C pointers. Master the use of pointer variables and operators to manipulate data structures effectively.
E N D
Programming in C Pointer Basics
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.
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
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.
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;
Pointer Declaration The declarationint *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. 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!
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( )
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 *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.)
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 *pInt = NULL; • Often used as the return type of functions that return a pointer to indicate function failure int *myPtr = myFunction( ); if (myPtr == NULL) /* something bad happened */ • Dereferencing a pointer whose value is NULL will result in program termination.
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; }
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; }
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.
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:%02d\n", hours, minutes); return 0; }
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 *pStudent; /* pStudent is a "pointer to struct student" */ /* make pStudent point to bob */ pStudent = &bob; /* use -> to access the members */ printf ("Bob's name: %s\n", pStudent->name); printf ("Bob's gpa : %f\n", pStudent->gpa); /* make pStudent point to sally */ pStudent = &sally; printf ("Sally's name: %s\n", pStudent->name); printf ("Sally's gpa: %f\n", pStudent->gpa); Note too that the following are equivalent. Why?? pStudent->gpa and (*pStudent).gpa /* the parentheses are necessary */
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 *pName; 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 bobsName = {“Bob”, “Smith”}; PERSON bob; bob.age = 42; bob.gpa = 3.4; bob.pName = &bobsName;
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.
teammates.c typedef struct player { char *name; struct player *teammate; /* can’t use TEAMMATE yet */ } TEAMMATE; 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; /* print the teammates by following*/ while (t != NULL) /* the teammate pointers until */ { /* there are no more teammates */ printf(“%s\n”, t->name); t = t->teammate; }