| |
对于C语言中的指针数组与数组指针,初次接触总会让人有些挠头,但用得多了就会觉得其实也就那么回事,所谓指针数组,就是数组,只不过它是元素为指针的数组,而所谓数组指针,就是指针,只不过它是指向数组的指针。
(1)
int a[3][4];//二维数组,存储int型的数值,编译器为这个二维数组分配了3*4个sizeof(int)的连续空间
(2)
int* b[4];//一维数组,存储int*型的数值,也就是人们常说的指针数组,该数组用来存储int型数据的地址,编译器为该一维数组分配了4个sizeof(int *)的空间
例如:
int a,b,c,d;
b[0] = &a;
b[1] = &b;
b[2] = &c;
b[3] = &d;
(3)
int (*p)[4];//这个稍微复杂一些。本语句表示的含义就是说:p是一个指向二维数组的首指针,并且这个二维数组低维的维数为4。因此,编译器只是为p分配了一个指针的空间,在32位系统中,一般是4个字节。由于它不是一个数组,因此,编译器也不会为之分配数组空间。
因此,如下赋值是不对的。
int a[3][5];
int (*p)[4] = a;//维数不匹配
但是你可以这样写:
int a[3][4];
int (*p)[4] = a;//你可以用p[1][2]等来调用a中的元素,就像用a[1][2]一样
另外还有一点,int (*p)[4] 不仅可以向上面所述的,给其赋予一个低维相同的二维数组的起始地址,它也可以用于函数参数的传递之中。可以参见最后代码中的ShowValue1。
(4)
另外二维数组在函数中的参数传递也经常采用
int p[][4]的形式。可以参考代码中的ShowValue2。
int (*p)[4]和int p[][4],都是用来指向一个低维空间为4 的二维数组的首地址。在函数的参数传递中,可见它们的效果是一样的。它们都只有一个指针的空间,因为他们只是用来记录一个数组的起始地址。
但是,int p[][4]还有不同之处。就是你不能在程序中使用
int p[][4];
或者
int a[3][4];
int p[][4]=a;
这种方式来为其赋值。它只能用于函数参数的传递。这是因为编译器在遇到 int p[][4]; 时,会将其视为普通的二维数组来处理,因此不能确定其大小,会编译出错。
但是你可以用
int n[][4] ={1,2,3,4,5,6,7,8,9,10,11,12};
来初始化一个常规的二维数组。
注意!!!
附参考代码:
#include "stdafx.h"
void ShowValue1(int (*p)[4])
{
int i,j;
for(i = 0; i< 3; i++)
{
for(j = 0 ; j < 4 ; j++)
printf("%d ",p[i][j]);
printf("\n");
}
}
void ShowValue2(int p[][4])
{
int i,j;
for(i = 0; i< 3; i++)
{
for(j = 0 ; j < 4 ; j++)
printf("%d ",p[i][j]);
printf("\n");
}
}
int main(int argc, char* argv[])
{
int i,j,k=0;
int a[3][4];
for(i = 0 ;i < 3; i++)
for(j = 0 ; j < 4 ; j++)
a[i][j] = k++;
int (*p)[4]; //可以首先定义,然后再赋值
p = a;
for(i = 0; i< 3; i++)
{
for(j = 0 ; j < 4 ; j++)
printf("%d ",p[i][j]);
printf("\n");
}
int (*c)[4] = a; //在定义时即进行初始化
for(i = 0; i< 3; i++)
{
for(j = 0 ; j < 4 ; j++)
printf("%d ",c[i][j]);
printf("\n");
}
//int l[][4];//error
//int m[][4] = a; //error
ShowValue1(a);
ShowValue2(a);
return 0;
}