C Programming 4

Download Report

Transcript C Programming 4

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.
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 *nameOfPointer;
7/28/09
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. 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!
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 *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.
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
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;
}
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 *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 */
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 *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;
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(“%s\n”, 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