第五章 指针
C语言的强大和良好的自由性绝大部分体现在指针的灵活运用上,指针可以说是C语言的灵魂。
一、不同类型指针之间的区别和联系
1.不同类型的指针
指针变量占用内存的大小与 它本身的类型无关,而是由使用的计算机决定的。但是不同类型的指针之间也是有区别的,因为不同类型的指针变量所指向内存区域的大小并不相同。“指针就是地址,地址就是指针”这种说法并不准确,忽略了类型的作用,指针应该是:地址+类型。
2.普通指针和数组指针
1 int index; 2 char a[4] = {'a','b','c','d'}; 3 char (*pa)[4]; 4 char *pb; 5 char *pc; 6 7 pa = &a; 8 pb = a; 9 pc = &a[0]; 10 11 printf("pa所指的地址:%d\n",pa); 12 printf("pb所指的地址:%d\n",pb); 13 printf("pc所指的地址:%d\n",pc); 14 15 printf("pa+1所指的地址:%d\n",pa+1); 16 printf("pb+1所指的地址:%d\n",pb+1); 17 printf("pc+1所指的地址:%d\n",pc+1); 18 19 for(index = 0; index < 4; index++) 20 { 21 printf("pa[%d]=%c\n", index, pa[0][index]); 22 printf("pb[%d]=%c\n", index, pb[index]); 23 printf("pc[%d]=%c\n", index, pc[index]); 24 }
上面的代码可以很好的诠释指针与数组的关系。运行结果如下:
其中有几个有意思的点:1)pa为什么定义成这样? 2)为什么pa、pb、pc分别+1的值不同? 3)怎么通过pa输出字符串?
二、指针与数组之间的关系
1.指针对于数组的引用
1 int a[3][3]; 2 int i,j; 3 int *p; 4 int (*pa)[3]; 5 6 for(i = 0; i < 3; i++) 7 { 8 for(j = 0; j < 3; j++) 9 { 10 a[i][j] = i*3+j; 11 } 12 } 13 14 p = a[0]; 15 for(i = 0; i < 9; i++) 16 { 17 printf("a[%d][%d] = %d ", i/3, i%3, p[i]); 18 if(i%3 == 2) 19 { 20 printf("\n"); 21 } 22 } 23 24 pa = a; 25 for(i = 0; i < 9; i++) 26 { 27 printf("a[%d][%d] = %d ", i/3, i%3, *(*pa+i)); 28 if(i%3 == 2) 29 { 30 printf("\n"); 31 } 32 }
2.通过指针数组创建动态数组
1 #define N 4 2 #define M 3 3 4 int i; 5 int j; 6 int index; 7 int *a[N]; 8 9 for(index = 0; index < N; index++) 10 { 11 //简单例子不做错误处理 12 a[index] = (int *)malloc(sizeof(int)*M); 13 } 14 15 for(i = 0; i < N; i++) 16 { 17 for(j = 0; j < M; j++) 18 { 19 a[i][j] = i*M + j; 20 printf("a[%d][%d] = %d ", i, j ,a[i][j]); 21 } 22 printf("\n"); 23 } 24 25 for(index = 0; index < N; index++) 26 { 27 free(a[index]); 28 } 29 30 #undef N 31 #undef M
3.通过数组指针创建动态数组
1 #define N 4 2 #define M 3 3 4 int i; 5 int j; 6 int (*a)[N]; 7 8 a = (int (*)[N]) malloc (sizeof(int)*M*N); 9 10 for(i = 0; i < M; i++) 11 { 12 for(j = 0; j < N; j++) 13 { 14 a[i][j] = i*N + j; 15 printf("a[%d][%d] = 0x%d ", i, j, a[i][j]); 16 } 17 printf("\n"); 18 } 19 20 for(i = 0; i < N; i++) 21 { 22 for(j = 0; j < M; j++) 23 { 24 a[i][j] = i*M + j; 25 printf("a[%d][%d] = 0x%d ", i, j, a[i][j]); 26 } 27 printf("\n"); 28 } 29 30 free(a); 31 32 33 #undef N 34 #undef M
上例书中的代码是有问题的,你能看出问题在那里吗?
4.指针数组对数组的引用
1 #define N 4 2 #define M 3 3 4 int i,j; 5 int *a[N]; 6 int b[N][M]; 7 8 for(i = 0; i < N; i++) 9 { 10 a[i] = b[i]; 11 for(j = 0; j < M; j++) 12 { 13 b[i][j] = i*M+j; 14 printf("a[%d][%d] = %d ", i, j, a[i][j]); 15 } 16 printf("\n"); 17 } 18 #undef N 19 #undef M
5.数组指针对数组的引用
1 #define N 4 2 #define M 3 3 4 int i,j; 5 int (*a)[M]; 6 int b[N][M]; 7 8 for(i = 0; i < N; i++) 9 { 10 a = b; 11 for(j = 0; j < M; j++) 12 { 13 b[i][j] = i*M+j; 14 printf("a[%d][%d] = %d ", i, j, a[i][j]); 15 } 16 printf("\n"); 17 } 18 #undef N 19 #undef M
注意和4中实例代码的区别