1 / 34

Pointers

Pointers. Pointers. What is pointer? A variable (2 or 4 bytes long) that can hold an Address Why pointers? Sometimes the only way to express a computation Usually lead to compact and efficient code Related operators: - * : can be used in two ways

susannee
Download Presentation

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

  2. Pointers • What is pointer? • A variable (2 or 4 bytes long) that can hold an Address • Why pointers? • Sometimes the only way to express a computation • Usually lead to compact and efficient code • Related operators: - * : can be used in two ways • In declaration : read as pointer, e.g., int *p; • In accessing : read as content of, e.g., x = *p; - & : returns LValue (address) of a variable • Read as address of

  3. 70 80 10 20 30 40 ???? 4892 4900 Pointer Examples int x = 70, y = 80, z[4] = {10, 20, 30, 40 }; int *ip; // int pointer ip ip = &x; // ip is assigned to address of x *ip = 200; // content of ip is assigned to 200 y = *ip; // y is assigned to content of ip ip = &z[2]; *ip = *ip + 20; // same as *ip += 20; y = *ip+1; 200 x : 4892 200 51 y : 4894 Z, Z[0] : 4896 Z[1] : 4898 50 Z[2] : 4900 Z[3] : 4902 ip : 4904

  4. Pointer Examples int x = 100; int *p1 = &x; cout << "&x == " << &x << " x == " << x << endl << "p1 == " << p1 << " *p1 == " << *p1 << endl; *p1 += 20; cout << "&x == " << &x << " x == " << x << endl << "p1 == " << p1 << " *p1 == " << *p1 << endl; Output &x == 0x7fff7e60f41c x == 100 p1 == 0x7fff7e60f41c *p1 == 100 &x == 0x7fff7e60f41c x == 120 p1 == 0x7fff7e60f41c *p1 == 120

  5. Pointers in Function arguments void swap_wrong(int x, int y) { int temp; temp = x; x = y; y = temp; } • Arguments are passed by value, thus only a copy is passed. in swap_wrong in swap 10 x: 4397 px: void swap(int *px, int *py) { int temp; temp = *px; *px = *py; *py = temp; } 20 y: 9643 py: temp: temp: in caller: int a = 10, b = 20; swap_wrong(a, b); cout << a << b; swap(&a, &b); cout << a << b; a:4397 10 b:9643 20

  6. pointer Referencing & Dereferencing & * [] variable • Referencing ( & ): create reference (pointer) to memory location • Dereferencing (*, [ ] ): get the content of memory location Note: x = 10;  *(&x) = 10;

  7. Pointer Operations • The valid pointer operations are: • Adding or subtracting a pointer and an integer (p  i) • Assignment of pointers of the same type (p = q) • Subtracting or comparing two pointers in same array (p - q) • Assigning or comparing to zero. (p = 0) • All other pointer arithmetic are illegal.

  8. 1– Addition/Subtraction with int • Used for pointing to different elements in an array int a[6], *pa, x, i; pa = &a[2]; // same as pa = a + 2; *pa  pa[0]  a[2] *(pa-i)  pa[-i]  a[2-i] *(pa+i)  pa[i]  a[2+i] pa-2 pa-1 pa: pa+1 pa+2 pa+3 a: a[0] a[1] a[2] a[3] a[4] a[5] pointer  int  pointer

  9. Addition/Subtraction with int • Size of the pointed data-type is automatically taken care of. • If address of a pointer (say ptr) is A then address of ptr+i is A+i*sizeof(data-type of ptr) long *lp; int *ip; char *cp; 12 7832 lp7832 *lp= 78563412 12 34 7832 7833 ip7832 *ip=3412 34 7834 56 7833 12 7834 56 7835 78 7832 cp7832 *cp=12 ip+17834 ip[1]=4456 34 7835 44 78 7833 7836 lp+17836 lp[1]= 12345678 7834 56 33 56 7836 7837 ip+27836 ip[2]=5633 cp+27834 cp[2]=56 7835 44 56 7838 34 7837 7839 12

  10. Assignment of Pointers • Pointers of same types can be assigned. float x = 10.5, *p = &x, *q = p; • Pointer to void • is used to hold any type of pointer int *ip; void *vp; vp = ip; // type casting is not essential • Cannot be de-referenced without type casting. int x = *vp; // is illegal type casting is a must int y = *((int *)vp); // is ok

  11. Comparing/Subtraction to Pointer • The resulting type of subtracting two pointers is integer. • Comparison Vs. Subtraction • a < b  a – b < 0 • a == b  a – b == 0 • a > b  a – b > 0 • Compared/Subtracted pointers should point in same array. • Example: /* strlen: return length of string s*/ int strlen(char *s) { char *p = s; while (*p != ‘\0’) p++; return p – s; } pointer - pointer  int

  12. Comparing/Assigning to Zero • Zero is the only integer that can be assigned to a pointer • Zero is the only integer that a pointer can be compared to. • Use this to initialize a pointer and to check validity char *m = 0; ... if (m != 0) { ... safe to use the pointer ... } • NULL can be used instead of 0

  13. Pointer Vs Array amessage: now is the time\0 now is the time\0 pmessage: char amessage[] = “now is the time”; // an array char *pmessage = “now is the time”; // a pointer • pmessage is pointer and requires 2/4 bytes for itself • pmessage++ is possible • pmessage=somepointer is legal • amessage is a name for the starting address of the array • amessage++ is illegal • amessage=somepointer is illegal

  14. strcpy example /* strcpy: copy t to s */ void strcpy(char *s, char *t) { int i; i = 0; while ((s[i] = t[i])!=‘\0’) i++; } Note: if you just write s=tthen only the pointer will be copied, not the characters /* strcpy: copy t to s */ void strcpy(char *s, char *t) { while ((*s = *t)!=‘\0’) { s++; t++; } } /* strcpy: copy t to s */ void strcpy(char *s, char *t) { while ((*s++ = *t++)!=‘\0’) ; }

  15. Pointer Vs Array • In function argument array and pointer are same. i.e., following declaration/definition of function are equivalent • int strlen(char *str) • int strlen(char str[ ]) • Arguments are passed by value, thus only a copy is passed. /* strcpy: copy t to s */ void strcpy(char *s, char *t) { while (*s++ = *t++) //DO NOTHING; } ……… char p[25]; char *q = “Hello world”; strcpy(p, q); 4397 s: 9643 t: 4397 p: q: Hello world\0 9643 What is the effect of writing s=t?

  16. strcmp example // strcmp: return <0 if s<t, 0 if s==t, >0 if s>t int strcmp(char *s, char *t) { int i; for (i = 0; s[i] == t[i]; i++) if (s[i] == ‘\0’) return 0; return s[i] – t[i]; } // strcmp: return <0 if s<t, 0 if s==t, >0 if s>t int strcmp(char *s, char *t) { for ( ; *s == *t; s++, t++) if (*s == ‘\0’) return 0; return *s – *t; }

  17. Dynamic Memory Management Program image in RAM Can be accessed via getenv function Environment variables char *gvar = “some string”; int max_size = 200; int myfunc(int x) { int y = 20; x = x + y; return x * y; } int main(void) { int *px = new int; cin >> x; cout << myfunc(x); delete px; } Static Data Stack Heap Program code

  18. Dynamic Memory Allocation // Allocating array int *parr = new int[10]; delete [] parr; // Allocating data for reference class Foo { …………}; Foo *p = new Foo(); p->c1 = ′X′; delete p; // explicit free // Allocating data for reference Foo &r = *new Foo(); r.c1 = ′X′; delete &r; // explicit free

  19. Pointer Anomalies • Uninitialized variable : Before storage can be used, it must be allocated. Foo *p; // forget to initialize pointer with “new” p->c1 = ′R′;// places ′R′ at random location in memory • After storage is no longer needed it must be explicitly deleted otherwise memory leak results. Foo *p = new Foo; p = new Foo; // forgot to free previous storage • After storage is deleted, it must not be used: delete p; p->c1 = ′R′; // result of dereference is undefined • p is called a dangling pointer.

  20. Pointers Vs. Multi-dim Arrays 20 m … • int m[10][20] • mis a 2D array: • 200 int sized locations have been set aside • m[row][col]is calculated as 20row+col • int *pm[10] • pmis a 1D array of pointers to int. • Only 10 pointers are allocated • pm[i] must be initialized/allocated with code (malloc) or static initialized (like name array) • int **ppm • cis a pointer of pointers to int. • Only 1 pointer is allocated • c must be initialized/allocated with code (malloc) • c[i] must be initialized/allocated with code (or static initialized (like name array) • Examples in next slide 10 … … … … pm 10 ppm

  21. Pointers Vs. Multi-dim Arrays 10 11 12 13 20 21 22 23 30 31 32 33 int m[3][4]; for (int r = 0; r < 3; r++) for (int c = 0; c < 4; c++) m[r][c] = (r+1)*10 + c; int *pm[3]; for (int r = 0; r < 3; r++) { pm[r] = new int[4]; for (int c = 0; c < 4; c++) pm[r][c] = (r+1)*10 + c; } int **ppm = new int *[3]; for (int r = 0; r < 3; r++) { ppm[r] = new int[4]; for (int c = 0; c < 4; c++) ppm[r][c] = (r+1)*10 + c; }

  22. 0 12 daytab daytab[0] [1] [12] Multi-dimensional Array : Formal Parameters • In function parameter only the left most dimension is unnecessary. • Thus all the following are equivalent: void func(int daytab[2][13]) { … } void func(int daytab[][13]) { … } void func(int (*daytab)[13]) { … } • The brackets in last statement is necessary since [ ] have higher precedence than *. • int (*daytab)[13] : a pointer to an array of 13 elements • int *daytab[13] : an array of 13 pointers to integers.

  23. Complicated Declarations • Read C declarations using a counter-clock wise spiral • Do not cross a bracket (**a[]) unless all the tokens within the bracket are finished int * f () int *f() f is a function returning int * int (*f)() int ( * fp ) () fp is a pointer to function returning int

  24. Complicated Declarations char (*(*x())[5])() [5] char ( * ( * x () ) ) () x is a function returning pointer to array[5] of pointer to function returning char char (*(*x[3])())[5] x is a array[3] of pointer to function returning pointer to array[5] of char

  25. [0] echo\0 [1] hello\0 [2] world\0 [3] 0 Command-line Arguments • main is called with two arguments : • int argc: is the number of command-line arguments • char **argv: pointer to array of strings (i.e., char *) int main(int argc, char **argv) • echo.c invoked with: echo hello world • argc is 3 and argv is  argv #include <iostream> int main(intargc, char **argv) { for (int i = 1; i < argc; i++) std::cout << argv[i] << " "; std::cout << endl; }

  26. Command-line Arguments /* Processing command-line options: like –abc –x –v */ int main(int argc, char **argv) { while (--argc > 0 && (*++argv)[0] == ‘-’) { // each option group while (c = *++argv[0]) { // for each option in the goup // process the option } } } find.exe\0 argv (*++argv)[0] ++argv (*++argv) - x f r \0 0 -m\0

  27. Command-line Arguments /* Processing command-line options: like –abc –x –v */ int main(int argc, char **argv) { while (--argc > 0 && (*++argv)[0] == ‘-’) { // each option group while (c = *++argv[0]) { // for each option in the group // process the option } } } find.exe\0 argv ++argv[0] argv[0] - x f r \0 *++argv[0] 0 -m\0

  28. Pointers to Functions • In C/C++, a function itself is not a variable • But pointer to function can be created • int (*comp)(void *, void *); • comp is a pointer to function that returns int and takes two void * type arguments • BEWARE: int *comp(void *, void *) • means that comp is a function that that returns int * and takes two void * type arguments • int result = (*comp)(&x, &y) • invokes comp with parameters x and y

  29. Pointer to Function : Example

  30. Be Careful with * and ++/-- • * and ++ / -- are executed from right to left char *p = “XAD”; char *q = p; char c; The above is also true for the – – operator.

  31. Coercion: Storage of Values in Memory long int • Same memory location can be interpreted in different ways: Intrepreted as 1 long int 41 43 45 47 0x41434547 short int 47 7832 Intrepreted as 2 short int 45 47 0x4547 45 7833 41 43 0x4143 7834 43 7835 41 char 47 ‘G’ Intrepreted as 4 char 4-bytes in RAM 45 ‘E’ Note: All numbers in this slide are in hexadecimal system. 43 ‘C’ Higher bits stored in higher address 41 ‘A’

  32. Coercion: Assignment of Pointers • Cast and then assign int i = 0x4145, *ip = &i; char *cp = (char *)ip; cout << *cp << endl << cp[1] << endl << showbase << hex << int (*cp) << endl << int (cp[1]) << endl << *ip << endl ; cp:8996 E *cp: 78 38 A *(cp+1): hi-8bits[7839] lo-8bits[7838] Logical View 45 i:7838 41 78 38 41 45 7839 *ip: ip:8976 RAM bytes

  33. lp:8974 78 32 47 l:7832 78 32 ip:8976 45 7833 78 32 cp:8978 43 7834 41 7835 RAM bytes Coercion: Assignment of Pointers • Cast and then assign long int l = 0x41434547, *lp = &l; int *ip = (int *)lp; // same as int *ip = (int *)&l; char *cp = (char *)lp; // same as char *ip = (char *)&l; Note: lp, ip and cp are all of size 2 bytes though they are pointing to data of different sizes, 4, 2 and 1 bytes, respectively.

  34. 47 *cp=‘G’ 47 7832 47 7832 7832 *ip 0x4547 45 *(cp+1) =‘E’ 45 7833 45 7833 7833 *lp 0x41434547 43 *(cp+2) =‘C’ 43 7834 7834 43 7834 *(ip+1) 0x4143 41 *(cp+3) =‘A’ 41 7835 7835 41 7835 RAM bytes RAM bytes RAM bytes Coercion: Assignment of Pointers • Cast and then assign long int l = 0x41434547, *lp = &l; int *ip = (int *)lp; char *cp = (char *)lp; cout << *cp << *(cp+1) << *(cp+2) << *(cp+3) << *ip << *(ip+1) << *lp;

More Related