1 / 49

Pointers

Pointers. Declaring, dereferencing, & assigning Call by value & reference Constant pointers Arrays (arithmetic, strings, pointers) Pointers to functions Command line arguments. Pointers. Pointers – variables that contain a memory address of another variable as its value

delta
Télécharger la présentation

Pointers

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Pointers • Declaring, dereferencing, & assigning • Call by value & reference • Constant pointers • Arrays (arithmetic, strings, pointers) • Pointers to functions • Command line arguments

  2. Pointers • Pointers – variables that contain a memory address of another variable as its value • What are they good for? • Generic access to several similar variables • Call by reference function parameters • Dynamically allocated data structures • Creating copies of arrays and structures

  3. Terminology • & operator – address operator • Returns the address of its operand • * operator – indirection or dereferencing operator • Returns the value of the object to which its operand points

  4. Terminology • Declaring a variable int num = 5; • Declaring a pointer int *nptr = 0; • Assigning an address to a pointer nptr = # • Dereferencing a pointer printf("%d",*nptr);

  5. Assigning an Address int num = 5; int *nptr = NULL; /*defined in .h files*/ nptr = # /*assign num's address to nptr*/ printf("num=%d &num=%p \n",num,&num); /* num=5 &num=0x244ff44*/ printf("*nptr=%d nptr=%p \n",*nptr,nptr); /* *nptr=5 nptr=0x244ff44*/

  6. Equivalent Code • int num = 10, *ptr = # • int num = 10; int *ptr = 0; ptr = #

  7. Dereferencing Pointers • With pointers, you can alter the value that the pointer is pointing to: int num=10, *nptr=# ++*nptr; /*unary operators associate*/ (*nptr)++; /*right to left*/ printf(" num=%d &num=%p\n",num,&num); printf("*nptr=%d nptr=%p\n",*nptr,nptr); /* num=12 &num=0x244ff44 *nptr=12 nptr=0x244ff44 */

  8. Dereferencing Pointers • Can also alter the actual pointer value, which may create an error: int x=3, num=6, y=9, *nptr=# nptr++; printf(" num=%d &num=%p\n",num,&num); printf("*nptr=%d nptr=%p\n",*nptr,nptr); /* num=6 &num=ffbefb40 *nptr=3 nptr=ffbefb44 */

  9. Assigning Pointers to Pointers • Must be of the same type • If not, must use a cast operator • Exception is type void • Generic pointer • Can be assigned to any pointer type • Any pointer type can be assigned to it • Cannot be dereferenced (must cast it first)

  10. Dereferencing Pointers • The compiler must know the data type to know how to dereference a pointer • For integer pointers, the compiler knows that it refers to 4-bytes in memory • Since a void pointer can be any data type, the compiler cannot dereference it

  11. Assigning Pointers to Pointers int num = 1234567890; /*0x499602D2*/ char ch = 'A'; int *iptr = # char *cptr = &ch; iptr = (int *)cptr; /*cast char pointer to integer pointer*/ printf("*iptr=%c\n",*iptr); /* *iptr=A (no data lost)*/ iptr = # cptr = (char *)iptr; /*cast integer pointer to char pointer*/ printf("*cptr=%d\n",*cptr); /* *cptr=-46 (loss of data)*/ /*0x499602D2 => D2 => 1101 0010 => -46*/

  12. Generic Pointer - void * int num = 1234567890; char ch = 'A'; int *iptr = # char *cptr = &ch; void *vptr = NULL; vptr = iptr; printf(“*vptr=%d\n",*((int *)vptr)); /* *vptr=1234567890 */ /* cast void to int pointer*/ vptr = cptr; printf(“*vptr=%c\n",*((char *)vptr)); /* *vptr=A */ /* cast void to a char pointer*/

  13. Call by Value • Changing the argument in the function does not change the original variable void swap1(int, int); . . . int num1=3, num2=7; swap1(num1,num2); printf("num1=%d num2=%d\n",num1,num2);   . . . /*num1=3 num2=7*/ void swap1(int a, int b){ int temp = a; a=b; b=temp;}

  14. Call by Reference • Changing the argument in the function does change the original variable void swap2(int *, int *); . . . int num1=3, num2=7; swap2(&num1,&num2); printf("num1=%d num2=%d\n",num1,num2); . . . /* num1=7 num2=3 */ void swap2(int *a, int *b){ int temp = *a; *a=*b; *b=temp;}

  15. Call by Reference • Another version – arguments are pointers void swap2(int *, int *); . . . int num1=3, *p1=&num1, num2=7, *p2=&num2; swap2(p1,p2); printf("num1=%d num2=%d\n",num1,num2); . . . /* num1=7 num2=3 */ void swap2(int *a, int *b){ int temp = *a; *a=*b; *b=temp;}

  16. Class Exercise 1 #include <stdio.h> void funA(void *, int); int main(){ int a = 10, b = 20, c = 30; int *ptr1 = &a, *ptr2 = &b, *ptr3 = &c; ptr3 = ptr2;  b++; (*ptr3)++; c = *ptr3; funA(ptr1, *ptr2); printf("%d %d %d\n",a,b,c); return 0; } void funA(void *a, int b){ int temp = *((int *)a); *((int *)a) = b; b = temp; }

  17. Constant Pointers int num1 = 3; int num2 = 7; int *const ptr1 = &num1; /*cannot change address in ptr1*/ int *ptr2 = &num2; num1++; /*no warning*/ (*ptr1)++; /*no warning*/ ptr1 = ptr2; /*gives warning*/

  18. Constant Pointers int num1 = 3, num2 = 7; const int *const ptr1 = &num1; /*cannot change address and cannot change value at that address*/ int *ptr2 = &num2; num1++; /*no warning*/ (*ptr1)++; /*gives warning*/ ptr1 = ptr2; /*gives warning*/

  19. Constant Pointers in Functions void swap2(const int *a, const int *b){ /*cannot change value at that address*/ int temp = *a; /*no warning*/ *a=*b; /*gives warning*/ *b=temp; /*gives warning*/ }

  20. Pointers & Arrays • In C, almost interchangeable • An array name can be thought of as a constant pointer • An array name is an address • Pointers can be used to do array subscripting • A pointer stores an address

  21. Pointers & Arrays int array[] = {1,2,3,4}; int *ptr = NULL; ptr = array; ptr = &array[0]; /*same as line above*/ printf("array[0] = %d\n",array[0]); printf("*(array+1)= %d\n",*(array+1)); printf("ptr[2] = %d\n",ptr[2]); printf("*(ptr+3) = %d\n",*(ptr+3)); /* array[0] = 1 *(array+1)= 2 ptr[2] = 3 *(ptr+3) = 4 */

  22. Alternative Array Loop int array[] = {1,2,3,4}; int *ptr = NULL; ptr = array; while(ptr!=(array+4)){ printf("%p = %d\n",ptr,*ptr); ptr++; } 0x257fc80 = 1 0x257fc84 = 2 0x257fc88 = 3 0x257fc8c = 4

  23. How are arrays stored? int in[]={1,2,3,4}; char ch[]={'a','b','c','d'}; int i=0; for(i=0;i<4;i++) printf("in[%d] = %p ch[%d] = %p\n",i,&in[i],i,&ch[i]); /* in[0] = 0x244ff30 ch[0] = 0x244ff2c in[1] = 0x244ff34 ch[1] = 0x244ff2d in[2] = 0x244ff38 ch[2] = 0x244ff2e in[3] = 0x244ff3c ch[3] = 0x244ff2f */

  24. Class Exercise 2 • What’s the output of the following code? • See exercise2.txt

  25. Pointer Arithmetic • Valid pointer operations • Assignment of pointers of the same type • Adding or subtracting a pointer & an integer • Comparing pointers of the same array • Assigning or comparing to zero • Invalid pointer operations • Add two pointers • Multiply, divide, shift, or and a pointer • Add float or double to a pointer • Assign pointers of different types without a cast

  26. /*Pointer Arithmetic*/ int i[] = {10,20,30,40}, *ip=i; ip+=3; /* 3*4=12 bytes */ printf(" i=%p *i=%d\n",i,*i); printf("ip=%p *ip=%d\n",ip,*ip); /* i=ffbefb38 *i=10 ip=ffbefb44 *ip=40 */

  27. /*Pointer Arithmetic*/ double d[] = {1.1, 2.2, 3.3, 4.4}, *dp=d; dp+=3; /* 3*8=24 bytes */ printf(" d=%p *d=%.1f\n",d,*d); printf("dp=%p *dp=%.1f\n",dp,*dp); /* d=ffbefb10 *d=1.1 dp=ffbefb28 *dp=4.4*/

  28. Character Pointers • char array[] = "this is an array"; • Array of characters + '\0' • Can change the characters in the array • Cannot change the array’s address • char *ptr = "this is a pointer"; • Points to constant characters + '\0' • Cannot change the string constant • Can change the pointer value

  29. Character Pointers #include <stdio.h> int main(){ char a[] = "character array"; char *b = "constant array"; a=b; /*compiler error: incompatible types in assignment*/ a[0]='C'; b[0]='A'; /*runtime error: Segmentation Fault*/ return 0; }

  30. String Copy • Must be careful when copying strings • Should copy each character to new string • Will create two different strings • Should not simply assign a new address • Will have two pointers pointing to the same string

  31. Bad String Copy #include <stdio.h> int main(){ char a[] = "character array"; char *b; b=a; b[0]='Z'; printf("%s\n",a); /*Zharacter array*/ printf("%s\n",b); /*Zharacter array*/ return 0; }

  32. Good String Copy #include <stdio.h> int main(){ char a[] = "character array"; char b[] = " "; char *ptr1 = a, *ptr2 = b; while(*ptr1!='\0') *ptr2++=*ptr1++; *ptr2='\0'; /*while(*ptr2++=*ptr1++);*/ b[0]='Z'; printf("%s\n",a); /*character array*/ printf("%s\n",b); /*Zharacter array*/ }

  33. Arrays of Pointers • Arrays can contain pointers • Common use is to have an array of strings const char *array[]={"zero","one","two"}; /*adds null character ('\0') to end*/ printf("%s\n",array[1]); /*one*/ printf("%s\n",*(array+1)); /*one*/ printf("%c\n",array[2][1]); /*w*/ printf("%c\n",*(*(array+2)+1)); /*w*/ if('\0'==array[0][4]) printf("true\n"); /*true*/

  34. Pointers to Functions • A pointer can also store the address of a function • A function name is the address in memory of the start of the function • Function pointers can be • Passed to a function • Returned to functions • Stored in arrays • Assigned to other function pointers

  35. An Array of Pointers to Functions #include <stdio.h> void fun1(void); void fun2(void); void fun3(void); int main(){ void (*array[3])(void) = {fun1,fun2,fun3}; /*declare an array of pointers to functions*/ int i; for (i=0;i<3;i++) (*array[i])();/*make a function call*/ return 0; /*output: 1st 2nd 3rd */ } void fun1(void){printf("1st ");} void fun2(void){printf("2nd ");} void fun3(void){printf("3rd ");}

  36. Alternative Code #include <stdio.h> void fun1(void); void fun2(void); void fun3(void); int main(){ void (*array[3])(void) = {fun1,fun2,fun3}; /*declare an array of pointers to functions*/ int i; for (i=0;i<3;i++) array[i](); /*or (*array[i])(); */ return 0; /*output: 1st 2nd 3rd */ } void fun1(void){printf("1st ");} void fun2(void){printf("2nd ");} void fun3(void){printf("3rd ");}

  37. Pointers to Functions void(*array[3])(void)={fun1,fun2,fun3}; • “array” is an array of 3 pointers to 3 functions with no arguments and return type void (*array[i])(void); array[i](); • The function is dereferenced and no arguments are passed to it

  38. An Array of Pointers to Functions II #include <stdio.h> int fun1(int); int fun2(int); int fun3(int); int main(){ int (*array[3])(int) = {fun1,fun2,fun3}; int i; for (i=0;i<3;i++) printf("%d ",(*array[i])(i)); /*1 3 5*/ /* printf("%d ", array[i](i)); */ return 0; } int fun1(intx){return x+1;} int fun2(intx){return x+2;} int fun3(intx){return x+3;}

  39. Pointers to Functions II int(*array[3])(int)={fun1,fun2,fun3}; • “array” is an array of 3 pointers to 3 functions with one int argument and return type int (*array[i])(i); array[i](i); • The function is dereferenced and integer “i” is passed as an argument to the function

  40. Passing Function Pointers to Functions #include <stdio.h> void fun1(int (*)(), float (*)()); int fun2(); float fun3();  int main(){ fun1(fun2,fun3); /*f1=12 f2=1.234000*/ return 0; }  void fun1(int (*f1)(),float (*f2)()){ printf("f1=%d f2=%f", f1(), f2()); } int fun2(){return 12;} float fun3(){return 1.234;}

  41. Passing Function Pointers void fun1(int (*)(), float (*)()); • “Fun1” is a function of return type void, that takes two arguments –a function pointer that returns an integer with no arguments,and a function pointer that returns a float with no arguments

  42. Passing Function Pointers fun1(fun2,fun3); • “fun1” is dereferenced with pointers to fun2 &fun3as arguments void fun1(int (*f1)(),float (*f2)()) • f1& f2 hold the addresses of fun2 & fun3

  43. Class Exercise 3 #include <stdio.h> void fun1(int(*)(int, int), float (*) (float, float)); int fun2(int,int); float fun3(float,float);  int main(){ fun1(fun2,fun3); return 0; }  void fun1(int (*f1)(int, int), float (*f2)(float, float)){ printf("f1=%d f2=%f", f1(6, 5), f2(1.5, 0.3));} int fun2(int a, int b){return a*b;} float fun3(float a, float b){return a/b;}

  44. Textbook Examples • Pointers to functions • Ascending or descending bubblesort • See bubble.c • Used in menu-driven system • See menu.c

  45. Class Exercise 4 #include <stdio.h> char *funA(char *); int main(){ char str[]="string"; char *cptr = funA(str); printf("%s\n",cptr); return 0; } char *funA(char *ch){ ch+=3; return ch; }

  46. Command-line Arguments int main(int argc, char *argv[]) • argc – “argument count” is number of command-line arguments the program was invoked with • argv – “argument vector” is a pointer to an array of character strings that contain the arguments

  47. Command-line Arguments int main(int argc, char *argv[]) • Can call these anything int main(int foo, char *bar[]) • Can also write *argv[] as **argv • a pointer to a pointer to a character

  48. Command-line Arguments /*Will repeat 1st line of text*/ #include <stdio.h> int main(int argc, char *argv[]){ int i=0; for(i=0;i<argc;i++) printf("%s ",argv[i]); printf("\n"); return 0; } /*See command.txt*/

  49. Program on UNIX • uhunix2: a.out* one two three • a.out one two three • uhunix2: a.out* one two <three • a.out one two

More Related