1.14k likes | 1.3k Vues
3 – Pointers. Why Pointer Variable s ?. most difficult part of C the most useful can use them to code call by reference can use them to build lists, queues, stacks, trees , etc. x. int x;. x. 1232. Boxes Again. The box occurs at memory addres s 1232. 1232. y. int * y ;. x. 1232.
E N D
Why Pointer Variables ? • most difficult part of C • the most useful • can use them to codecall by reference • can use them to build lists, queues,stacks, trees, etc.
x int x; x 1232 Boxes Again The box occurs at memory address 1232
1232 y int *y; x 1232 What is a Pointer Variable ? • A pointer variable can contain the memory address of another variable. int x;
Declaring a Pointer Variable int *countptr; Read this declaration ‘backwards’: countptr can contain the address of an integer variable or (more usually): countptr can point to an integer variable
Assignment to Pointers • The operator for returning the address of a variable is & int x = 5; int *countptr; countptr = &x;
x int x = 5; 5 1232 countptr int *countptr; ? countptr = &x; countptr 1232 Usually, drawn as: x countptr 5 Assigment in Pictures
Some Tricky Things int a;int *aptr;aptr = &a; is equivalent to: is equivalent to: But, int a, *aptr;aptr = &a; int a, *aptr = &a; int *aptr = &a, a; /* WRONG */
Initialising a Pointer int *xptr; float *yptr; xptr = NULL; yptr = NULL;
26634232 Result: Accessing a Pointer int c = 13;int *countptr; countptr = &c;printf("The value of countptr is %lu\n", countptr);
Result: 13 printf("The value of the integer pointed to by countptr is %d\n",*countptr); • This is called dereferencing a pointer
Two Uses of * int *countptr; means countptrcan point to an integer variable All other occurrences of * mean dereference: printf("...", *countptr);
a gptr int a = 3; *gptr; 3 ? a gptr gptr = &a; 3 a gptr *gptr = 7; 7 More Examples
a gptr *gptr = *gptr + 2; 9 a gptr (*gptr)++; 10
The & and *Operators #include <stdio.h>int main(){ int a = 7; int *aptr; aptr = &a; /* continued on next slide */
printf("Address of a is %lu\n", &a); printf("Value of aptr is %lu\n\n", aptr); printf("Value of a is %d\n", a); printf("Value of *aptr is %d\n\n", *aptr); printf("%s\n", "Proving that * and & are complements of each other."); printf("&*aptr = %lu\n", &*aptr); printf("*&aptr = %lu\n", *&aptr); return 0;}
Address of a is 2042756Value of aptr is 2042756 Value of a is 7Value of *aptr is 7 Proving that * and & are complements of each other. &*aptr = 2042756*&aptr = 2042756
Expression Equivalent Expression Value p == &i p == (&i) 1 (true) p = i + 7 p = (i + 7) illegal **&p *p 3 r = &x r = (&x) illegal Declarations and Initialisations int i = 3, j = 5, *p = &i, *q = &j, *r;double x; int double
Coding Call by Reference • Call by Value Reminder • Call by Reference Version • Swapping
Call by Value Reminder /* increment using call by value */ #include <stdio.h> int add1(int);int main(){ int count = 7; printf("The original value of count is %d\n", count); count = add1(count); printf("The new value of count is %d\n", count); return 0;}
int add1(int c){ return c++; /* increments local var c */} The original value of count is 7The new value of count is 8
Call By Reference /* Incrementing a variable using call by reference coded with pointers */ #include <stdio.h>void addp1(int *);int main(){ int count = 7; printf("The original value of count is %d\n", count); addp1(&count); printf("The new value of count is %d\n", count); return 0;}
void addp1(int *countptr){ (*countptr)++; /* increments count in main() */} The original value of count is 7The new value of count is 8
addp1() in pictures int main(){ ... addp1(&count); ...} count 7 void addp1(int *countptr){ (*countptr)++;} countptr
Swapping #include <stdio.h> void swap(int *, int *); int main(){ int a = 3, b = 7; printf("%d %d\n", a, b); /* 3 7 printed*/ swap(&a,&b); printf("%d %d\n", a, b); /* 7 3 printed*/ return 0;}
void swap(int *p, int *q){ int tmp; tmp = *p; *p = *q; *q = tmp;}
Swap() int main(){ int a =3, b = 7; ... swap(&a, &b); ...} a b 3 7 p q void swap(int *p, int *q){ int tmp; tmp = *p; *p = *q; *q = tmp;} tmp
Bubble Sort without Pointers #include <stdio.h>#define SIZE 10void array_swap(int [], int, int);int main() { int a[SIZE]={2,6,4,8,10,12,89,68,45,37}; int cntr, pass; printf("Data items in original order\n"); for (cntr = 0; cntr < SIZE; cntr++) printf("%4d", a[cntr]); : continued
for (pass = 0; pass < SIZE-1; pass++)for (cntr = 0; cntr < SIZE-1; cntr++) if (a[cntr] > a[cntr+1])array_swap(a, cntr, cntr+1); printf("\nItems in ascending order\n"); for (cntr = 0; cntr < SIZE; cntr++)printf("%4d", a[cntr]); printf("\n"); return 0;} continued
void array_swap(int a[], int x, int y)/* swap a[x] and a[y] */{ int temp; temp = a[x]; a[x] = a[y]; a[y] = temp;}
Bubble Sort with Pointers #include <stdio.h>#define SIZE 10void swap(int *, int *);int main() { int a[SIZE]={2,6,4,8,10,12,89,68,45,37}; int cntr, pass; printf("Data items in original order\n"); for (cntr = 0; cntr < SIZE; cntr++)printf("%4d", a[cntr]); : continued
for (pass = 0; pass < SIZE-1; pass++)for (cntr = 0; cntr < SIZE-1; cntr++) if (a[cntr] > a[cntr+1])swap(&a[cntr], &a[cntr+1]); printf("\nItems in ascending order\n"); for (cntr = 0; cntr < SIZE; cntr++)printf("%4d", a[cntr]); printf("\n"); return 0;}
void swap(int *x, int *y)/* swap x and y */{ int temp; temp = *x; *x = *y; *y = temp;}
Pointers to Arrays • An Array is a Sequence of Boxes • A Pointer Can Point at an Array Element • Moving the Pointer Along the Array • Moving the Pointer Backwards • The Difference Between Two Pointers • Allowable Pointer Arithmetic • Pointers and Relational Operators • Four Ways of Referring to Array Elements • Arrays and Pointers are Different
a[0] a[1] a[2] a[0] a[1] a[2] 2345 2349 2353 An Array is a Sequence of Boxes int a[3]; Memory addresses shown:
a[0] a[1] a[2] 5 7 2 2345 2349 2353 A Pointer Can Point at an Array Element int a[3], *aptr; :aptr = a; aptr
a[0] a[1] a[2] 5 7 2 2345 2349 2353 Another way of achieving aptr = &a[0]; printf("%d", *aptr); /* 5 printed */ aptr
a[0] a[1] a[2] 5 7 2 aptr 2345 2349 2353 Moving the Pointer along the Array aptr = aptr + 2; • Results in: printf("%d", *aptr); /* 2 printed */
a[0] a[1] a[2] 5 7 2 aptr 2345 2349 2353 Moving the Pointer Backwards aptr = aptr - 1; • Results in: printf("%d", *aptr); /* 7 printed */
The Difference Between Two Pointers void main(){double db[3], *p, *q; p = &db[0]; q = p + 1; printf("%d\n", q - p); /* 1 printed */ printf("%d\n", (int)q - (int)p); /* probably 8 is printed */}
db[0] db[1] db[2] p 1009 1017 1025 q In picture form:
Allowable Pointer Arithmetic int g[6], *p; *q p = g;/* same as &g[0] */ q = g; • All the following are possible: ++p p-- p += 5 p = p - 2 p - g • Only use Pointer Arithmetic with Arrays
n[0] n[1] n[2] nptr1 5135 5139 5143 nptr2 Pointers and Relational Operations int n[3], *nptr1, *nptr2;nptr1 = &n[0];nptr2 = n + 2;if (nptr2 > nptr1) /* 5143 > 5135? */ . . . ;
Four Ways of Referring to Array Elements! int b[5], *bptr; bptr = b;/* could also write bptr = &b[0] */ printf("4th element of b is %d\n", b[3] );/* ordinary array subscripting */
printf("4th element of b is %d\n",*(bptr+3));/* pointer/offset with a pointer */ printf("4th element of b is %d\n",*(b+3));/* pointer/offset with the array name */ printf("4th element of b is %d\n",bptr[3]);/* pointer subscript notation */
Arrays and Pointers are Different int a[3], *p;/* The following statements are illegal because they attempt to change a */a = p;++a;a += 2; An array is sometimes called a “constant pointer”
Using Array Pointers in Functions • Array and Pointer Correspondence • Three Ways to Sum an Array
Array and Pointer Correspondence void function_name(int [], int, . . .); :void function_name(int arr[], int x, . . .){ /* implementation */}
int arr[]is equivalent to int *arr void function_name(int *, int, . . .); :void function_name(int *arr, int x, . . .){ /* same implementation */}