Escolar Documentos
Profissional Documentos
Cultura Documentos
Pointers (2.7.2)
Pointer Examples
int x = 70, y = 80, z[4] = {10, 20, 30, 40 }; int *ip; ip = &x; *ip = 200; y = *ip; ip = &z[2]; *ip = *ip + 20; y = *ip+1; // int pointer ip // ip is assigned to address of x // content of ip is assigned to 200 // y is assigned to content of ip // same as *ip += 20; x : 4892 y : 4894 Z, Z[0] : 4896 Z[1] : 4898 Z[2] : 4900 Z[3] : 4902 ip : 4904
2
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;
Pointer Examples
int x = 100; int *p1 = &x; cout << "&x == " << &x << " << "p1 == " << p1 << " *p1 += 20; cout << "&x == " << &x << " << "p1 == " << p1 << " x == " << x << endl x == " << x << endl *p1 == " << *p1 << endl;
pointer
& variable
* []
Referencing ( & ): create reference (pointer) to memory location Dereferencing (*, [ ] ): get the content of memory location
Declaration int x; Reference/Pointer/ Address/LValue &x z z+i &z[i] ptr ptr+i &ptr[i] Dereference/Variable/ Content/RValue x z[0] *(z+i) z[i] *ptr or ptr[0] *(ptr+i) ptr[i] *(&x) = 10;
6
in swap_wrong
x: y: temp: 10 20
in swap
px: 4397 py: 9643 temp:
int z[10], i;
Output
&x == 0x7fff7e60f41c x == 100 p1 == 0x7fff7e60f41c *p1 == 100 &x == 0x7fff7e60f41c x == 120
in caller:
a:4397 b:9643 10 20
int *ptr, i;
Note: x = 10;
5
Pointer Operations
The valid pointer operations are 1. Adding or subtracting a pointer and an integer (p i) 2. Assignment of pointers of the same type (p = q) 3. Subtracting or comparing two pointers in same array (p - q) 4. Assigning or comparing to zero. (p = 0) All other pointer arithmetic are illegal.
12 34 56 78 78 56 34 12
9
12 34 56 44 33 56
pa-2
pa-1
pa:
pa+1 pa+2
pa+3
7832 7833
7833
12 34 56 44
7834 7835
22/02/2013
3 Comparing/Subtraction to Pointer
The resulting type of subtracting two pointers is integer. Comparison Vs. Subtraction a<bab<0 a == b a b == 0 a>bab>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; }
10
4 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 ... }
Pointer Vs Array
char amessage[] = now is the time; // an array
amessage: now is the time\0
strcpy example
/* strcpy: copy t to s */ void strcpy(char *s, char *t) { int i; i = 0; while ((s[i] = t[i])!=\0) i++; }
Pointer Vs Array
Note: if you just write s=t then only the pointer will be copied, not the characters
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[ ])
char *pmessage
pmessage:
pmessage has LValue pmessage is pointer and requires 2/4 bytes for itself pmessage++ is possible pmessage=somepointer is legal amessage has no LValue amessage is a name for the starting address of the array amessage++ is illegal amessage=somepointer is illegal
13
s: t:
4397 9643
/* 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) ; }
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]; }
References
const qualifier can be used with pointers in three ways: Prohibit a pointer from changing its content
const int *p1 = &w; // p1 can point to (non-)const int *p1 = 200; // invalid : content cant change p1 = &x; // OK. p1 points to x (non-const) int const *p2; // p2 and p2 is identical to
References must be initialized at declaration and cant change Referencing and dereferencing are implicitly done by C++
r1 = r1 + 5 + w; // not for using *r1
int * const p3 = &x; // must be initialized at creation p3 = &y; // invalid: reference cant change *p3 = 123; // OK. changes value of x
16
22/02/2013
2.15 p-89
Pointer Anomalies
Uninitialized variable : Before storage can be used, it must be allocated.
Foo *p; p->c1 = R; // forget to initialize pointer with new // places R at some 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
Heap
Program code
21
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
10 11 12 13 20 21 22 23 30 31 32 33
pm
10
The brackets in last statement is necessary since [ ] have higher precedence than *.
int (*daytab)[13] : a pointer to an array of 13 elements
0 daytab 12
daytab[0] [1]
[12]
24
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
Complicated Declarations
char (*(*x())[5])()
Command-line Arguments
(2.11 p-79)
char ( * ( * x () ) [5] ) ()
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)
int *f()
int * f ()
char (*(*x[3])())[5]
int (*f)() int ( * fp ) () fp is a pointer tofunction returning int
#include <iostream> int main(int argc, char **argv) { for (int i = 1; i < argc; i++) std::cout << argv[i] << " "; std::cout << endl; }
[2] [3]
22/02/2013
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 } } }
argv ++argv (*++argv) 0 x f r
\0
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]) { // process the option } } }
argv ++argv[0] argv[0] 0 x f r
\0
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
find.exe\0 (*++argv)[0]
find.exe\0
*++argv[0] -m\0
-m\0
28
29
30
Be Careful with * and ++/-* and ++ / -- are executed from right to left
char *p = XAD; char *q = p; char c;
41
43
45
47
0x41434547
Statement
c = ++*q; c = *++q; c = *q++;
q p p+1 p+1 p
Comment
Increment content of q and return new value. (*q)++; c = *q; Increment q and fetch content. q++; c = *q; fetch content of q and then increment q. i.e., c = *q; q++; Return content of q and then increment content of q. i.e. c = *q; (*q)++;
47 45 43 41
Intrepreted as 2 short int
0x4547 0x4143
4-bytes in RAM
Intrepreted as 4 char
45 43
c = (*q)++; X YAD
41
78 32 78 32 78 32
47 45 43 41
ip:8976 cp:8978
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.
47 45 43 41
47 45 43 41
*(ip+1) 0x4143 *ip 0x4547
47 45 43 41
*lp 0x41434547
41 45
34
RAM bytes
35
RAM bytes
RAM bytes
RAM bytes
36