这两个看起来很相似,但是却完全不一样。下面先说下数组指针。
数组指针,例如int(*p)[5],定义了一个数组指针,它指向指向包含5个int型元素的一维数组。来个程序看看。
1 #include<stdio.h> 2 int main() 3 { 4 int c[4]={1,2,3,4}; //定义一个整型数组 5 int (*b)[4]; //定义一个指向为int()[4]类型的数组指针 6 b=&c; //将c数组的地址赋给b 7 printf("%d",*(*b+1)); //*b+1为c数组第二个元素的地址 8 return 0; 9 }
上面这个程序的会输出c数组第二个元素的值,也就是2。其中第6行,将数组c的地址赋给指针b,虽然&c、c和&c[0]的值都相等,都表示数组的首地址,但是三者意义不同,c和&c[0]都表示数组第一个元素的地址,+1跨过1个数组元素;而&c表示整个数组的地址,+1跨过一个数组,即指向c[5],(虽然不存在)。
可以看下这个程序
1 int main() 2 { 3 int a[4]={1,2,3,4}; 4 int *p=(int *)(&a+1); //定义一个整型指针指向(&a+1) 5 p=p-1; //让p减1即减去一个int型的大小 6 printf("%d",*p); //输出p指向的值为a[3];可见&a+1的即为a[4]的地址 7 printf("%d",*(&a[0]+1)); //输出为a[1]的值 8 printf("%d",*(a+1)); //输出为a[1]的值 9 return 0; 10 }
现在再来看一个程序
1 int main() 2 { 3 int i,j; 4 int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12}; 5 int(*p)[4]; 6 p=a; //把a当做一个一维数组,其中每个元素又是一个含4个元素的数组 7 for(i=0;i<3;i++) 8 for( j=0;j<4;j++) 9 printf("%d",*(*(p+i)+j)); 10 /*其中*p+j表示二维数组a[0][j]的地址,*(p+i)+j表示a[i][j]的地址*/ 11 return 0; 12 }
这里直接把二维数组当做一维数组来处理。
讲了半天,估计还是有点乱,现在总结下,数组指针,就是指针,只不过指向的为数组,可以通过它来访问数组,前提是数组的类型要和指针指向的类型相同。
现在在来看看指针数组,总结上面的经验,看下这个的名字,应该能猜到它是一个数组,对的,它也是一个很普通的数组,只不过里面全存的是指针而已。
来看下这个,int *a[3],表示a是一个指针数组,它有三个数组元素,每个元素值都是一个指针,指向整型变量。
可以用一个指针数组来指向一个二维数组
1 int main() 2 { 3 int i,j; 4 int a[2][3]={1,2,3,4,5,6}; 5 int *b[2]={a[0],a[1]}; //定义一个指针数组,里边的元素为a数组第一维和第二维的地址。 6 for(i=0;i<2;i++) 7 for(j=0;j<3;j++) 8 printf("%d",*(*(b+i)+j)); 9 /*其中(b+i)表示b[i]的地址,*(b+i)表示a[i]的地址,(a[i]+j)表示i行j列元素地址*/ 10 printf(" %p %p ",b[0],a[0]); 11 return 0; 12 }
输出结果为
1 123456 2 0xbfa12e34 0xbfa12e34
可见b数组中存的为a数组一维地址。
指针数组还可以用于字符串的储存
1 int main() 2 { 3 int i; 4 char *str[]={"你","我","他"}; //数组中存的为字符串常量的地址 5 for(i=0;i<3;i++) 6 printf("%s",str[i]); 7 printf("%p",str[0]); //通过这行和下行比较两个地址是否相同 8 printf("%p","你"); 9 return 0; 10 }
这部分的内容还是比较难的,一定要多看,多理解,加油!!!