Professional Documents
Culture Documents
Pointers in C
1
3/2/2011
2
3/2/2011
Pointer Operations in C
"v and w are variables of type int"
"pv is a variable containing the address of another
variable"
pv = & v;
w = * pv;
C Pointer Operators
3
3/2/2011
…Operators (cont’d)
& = “the address of…”
int a; “ap is a pointer
int *ap; to an int”
…Operators (cont’d)
* = “pointer to…”
“the variable ap points to (i.e., a) is assigned value
*ap = 33; 33”
b = *ap; “b is assigned the value of the variable pointed to by
ap (i.e., a)”
4
3/2/2011
Addr Contents
0 Value of b
4 Value of c
8 Value of a
10
5
3/2/2011
11
6
3/2/2011
???
13
Pointers to Pointers to …
A C expression
char * ap = &a; Addr Contents Var
char ** app = ≈ 0 Value of b b
char *** appp = &app;
***appp = b + c; 4 Value of c c
8 Value of a a
Var Address
12 8 (addr of a) ap
a 8
ap 12 16 20 (addr of app) appp
app 20 20 12 (addr of ap) app
appp 16
b 0
32 bits (4 bytes) wide
c 4 14
7
3/2/2011
Why Pointers?
Indirection provides a level of flexibility that is
immensely useful
“There is no problem in computer science that cannot be
solved by an extra level of indirection.”
15
…Types (cont’d)
Make sure pointer type agrees with the type of the
operand it points to
int i, *ip;
float f, *fp;
16
8
3/2/2011
char * cp = …;
float * fp = …;
….
fp = (float *) cp; /* casts a pointer to a char
* to a pointer to a float???
*/
17
…Conversions (cont’d)
However, casts of variables pointed to are useful
float f;
int i;
char * ip = &i ;
…
f = * ip; /* converts an int to a float */
c = i ; /* no different! */
18
9
3/2/2011
1. ap = &c;
2. *ap = 3333;
… Bloopers (cont’d)
5. dp = ap; int a, b, *ap, *bp;
char c, d, *cp, *dp;
float f, g, *fp,
6. dp = ‘Q’; *gp;
7. fp = 3.14159;
8. gp = &fp;
9. *gp = 3.14159;
21
10
3/2/2011
… Bloopers (cont’d)
10. *fp = &gp; int a, b, *ap, *bp;
char c, d, *cp, *dp;
float f, g, *fp, *gp;
12. b = *a;
13. b = &a;
23
Sense…
Initially: int a, b, *p1,
*p2;
a = 30, b = 50;
p1 = & a;
OK: p2 = & b;
11
3/2/2011
…and Nonsensibility
Initially: int a, b, *p1, *p2;
a = 30, b = 50;
p1 = & a;
Not OK: p2 = & b;
<anything> = &35; a = **p2;
<anything> = *35; p1 = b;
p1 = 35; p1 = &p2;
a = &<anything>; p1 = *p2;
a = *b; <anything> = *b;
*a = <anything>; *p1 = p2;
&<anything> = <anything>; *p1 = &<anything>;
a = p2;
26
27
12
3/2/2011
28
29
13
3/2/2011
30
31
14
3/2/2011
15
3/2/2011
34
Alternative…
int s = 0;
sumit(3, &s); printf("%d\n", s);
sumit(4, &s); printf("%d\n", s);
sumit(5, &s); printf("%d\n", s);
35
16
3/2/2011
36
37
17
3/2/2011
38
Arrays R’ Pointers
Ex.: adding together elements of an array
Version 0, with array indexing:
39
18
3/2/2011
int sum = 0;
for (ap = &(nums[0]); ap < &(nums[3]); ap++)
sum += *ap;
41
19
3/2/2011
Pointer Arithmetic
Q: How much is the increment? Add 4 to the address
…Arithmetic (cont’d)
Array of ints
Symbolic Address Byte Addr Contents
nums Start of nums 10
nums+1 Start of nums + 4 20
nums+2 Start of nums + 8 30
Array of chars
Symbolic Address Byte Addr Contents
nums Start of nums 10
nums+1 Start of nums + 1 20
nums+2 Start of nums + 2 30
43
20
3/2/2011
…Arithmetic (cont’d)
Referencing the ith element of an array
44
45
21
3/2/2011
result =
scanf(“%c %9s %d %lf”, &c, str, &j, &num);
46
22
3/2/2011
…Multidimensional (cont’d)
Remember:
Equivalent: rain is the address of the
entire array
double *yp, *mp;
rain[3] is the address of
yp = rain[3]; the 4th row of the array
mp = yp + 5; inconsistent?
rain[3][5] is the value of
*mp = 2.4; the 6th element in the 4th
row
48
49
23
3/2/2011
50
cp = strings[2];
printf (“%c\n”, *(cp+3));
51
24
3/2/2011
52
25
3/2/2011
…Unequal (cont’d)
Ex., using pointers
char *strings[4] =
{ “Blue”, “Green”, “Orange”, “Red” };
char *cp = strings[3];
printf (“%s\n”, cp);
for ( int i = 0; i < 4; i++) {
int len = 0;
cp = strings[i];
while (*cp++ != ‘\0’)
len += 1;
printf(“length %d = %d\n”, i, len);
}
cp = strings[2] + 3;
printf (“%c\n”, *cp);
55
26
3/2/2011
rec2
value = 5 “EF” next = NULL
rec3
value = 4 “CD” next = &rec2
Pointers to Functions
Another level of indirection: which function you
want to execute
Example: giving raises to employees
Type A employee gets $5000 raise, type B get $8000
Two ways to do it
1. caller tells callee how much raise to give
2. caller tells callee what function to call to get the amount of
the raise
57
27
3/2/2011
Approach #1
float sals[NUMOFEMPLOYEES];
void raise (int empnum, int incr );
…
int emp1 = …;
(void) raise ( emp1, 5000 );
…
void raise (int empid, int incr)
{
sals[empid] += incr; /* give the employee
* a raise */
}
58
Approach #2
float sals[NUMOFEMPLOYEES];
void raise (int, int () );
int raiseTypeA ( int );
int raiseTypeB ( int );
int emp1 = …;
(void) raise ( emp1, raiseTypeA );
…
void raise ( int empid, int raiseType () )
{
sals[empid] += raiseType (empid);
}
…
int raiseTypeA (int eid) { … };
int raiseTypeB (int eid) { … };
59
28
3/2/2011
A Better Example
Standard library function for sorting:
starting address of array to be sorted
void qsort (in place)
29