指標 Pointers
int a = 5; int * ptr; // pointer to int ptr = &a; // 取a位址 // int *ptr = &a; *ptr = 10; // 設定指向位址的值 printf(“a = %d\n”, a); // a = 10
int a = 5; int * ptr = &a; *ptr = 10; ptr 位址 1236 1240 1244 1248 1252 1256 值 ?? 1304 a 位址 1296 1300 1304 1308 1312 1316 值 ?? 10 5
小心 int* a, b; // X: b is int!! int *a, *b; // O
小心 Segmentation fault int * ptr; … *ptr = 10; ptr 位址 1236 1240 1244 1248 1252 1256 值 ?? ??
好習慣 int *ptr = NULL; … if(ptr==NULL){ /* error */ } else *ptr = 10;
指標&陣列 char s[16]; char *ptr = s; // 相當於ptr = &s[0]; strcpy(s, “OAO”); printf(“%s\n”, ptr); // OAO putchar(ptr[1]); // A
動態記憶體配置 C style: malloc(), free() int *ptr = malloc(100*sizeof(int)); for(int i=0; i<100; i++) ptr[i] = i; free(ptr); C++ style: new[], delete[] int *ptr = new int[100]; for(int i=0; i<100; i++) ptr[i] = i; delete [] ptr;
小心 int arr[100]; memset(arr, 0, sizeof(arr)); // sizeof(arr) == sizeof(int[100]) // (400 bytes) int *ptr = new int[100]; memset(ptr, 0, sizeof(ptr)); // sizeof(ptr) == sizeof(int*) // (4 bytes)
struct struct XD { int a, b; }; XD xd; xd.a = 2; XD *ptr = &xd; ptr->b = 3; // or (*ptr).b
你可以… void my_strcpy(char *dst, char *src) { for(; *src!=‘\0’; dst++, src++) *dst = *src; } char s1[16], s2[16]; scanf(“%s”, s2); my_strcpy(s1, s2); // my_strcpy(&s1[0], &s2[0])
pointer to pointer int **pp, *p, a; p = &a; pp = &p;
array of pointers int *pa[20], n; pa[2] = &n;
pointer to array int (*pa)[20], arr[20]; pa = &arr;
你可以… int *mat[20], n; scanf(“%d”, &n); for(int i=0; i<20; i++) mat[i] = new int[n]; mat[3][n-2] = 8; delete [] mat[i];
你可以… int **mat, n, m; scanf(“%d%d”, &n, &m); mat = new int*[n]; for(int i=0; i<n; i++) mat[i] = new int[m]; mat[n-2][m-3] = 100; delete [] mat[i]; delete [] mat;
你不可以… void proc(int **mat){ mat[2][3] = 5; } int main() { … proc(mat); // error } gcc: cannot convert ‘int(*)[20]’ to ‘int**’
你可以… void proc(int (*mat)[20]); void proc(int mat[20][20]); ***不建議***
結語 善用指標,可以讓程式更簡潔易懂、更好維護 亂用指標 → 輕鬆RE