数组的数组,以及二维数组做形参
近日整理些小程序, 牵扯到数组的数组,二维数组等,小小的整理一下。
1. 数组的数组. 传递一堆整型数组作为一个函数参数.
有说,数组名就是指针,且不论这句话是否绝对正确,这句话可以作参考.
定义一个数组名的指针数组.
int IntArray1[3] = {1,2,3};
int IntArray2[3] = {4,5,6};
int IntArray3[5] = {7,8,9};
int IntArray4[3] = {10,11,12};
int IntArray5[4] = {13,14,15,16};
int *IntArray[5] = {IntArray1,IntArray2,IntArray3,IntArray4,IntArray5}; //指针数组
1)直接使用:
for(i = 0; i < 5 ; i++){ //5是指针数组的长度
for(j = 0; j < 3; j++){//3是一堆数组里最小长度,这里完全可以由另一个数组来记录各数组的准确长度
printf("%d\t",IntArray[i][j]);
}
printf("\n");
}
2) 做参数传递:
int test(int **Array) //也可以是*Array[]
{
int i,j;
for(i = 0; i<5; i++){
printf("Array[%d] addr = %p\n",i,Array[i]); //输出可以证明传入的是指针,是每个数组的首地址
for(j = 0; j < 3; j++){
printf("%d\t",Array[i][j]);
}
printf("\n");
}
return 0;
}
其实这里和常用的字符串数组没有区别.
char str1[] = "Just For Test";
char str2[] = "Just Do it";
char str3[] = "This is the End";
char *str[] = {str1,str2,str3};
单纯从简单应用来讲数组的数组等同于指针数组.
2. 二维数组做形参.
1)测试函数:
//定义一个二维数组
int NewArray[5][3] = {{1,2,3},{4,5,6},{7,8,9},{10},{11}};
int Test(int **array)
{
int i,j;
for(i = 0; i<5; i++){
for(j = 0; j < 3; j++){
printf("%d\t",*(Array+i*3+j));
}
printf("\n");
}
return 0;
}
int main()
{
Test(NewArray);
return 0;
}
编译报警告信息:
warning: passing argument 1 of 'test' from incompatible pointer type
warning note: expected 'int **' but argument is of type 'int (*)[3]'
能够准确输出信息,调用成功. 这里是将 int (*)[3] 转换成了 int **;
通过这个warning信息可以看出 二维数组 数组名的类型是 int (*)[], 而不是 int **;
如果把Test函数改为:
int Test(int *array)
{
........//不做改变
}
把调用改为
Test(*NewArray);
编译无警告,而且输出正常.
很明显 *NewArray 是一个int型的指针, 也就是说NewArray是一个指向指针的指针.... 开始晕了吧.
具体原因留在以后分析,目前这里只管应用,不探究指针和数组名内部实现的关系.
查看数组首地址:
printf("NewArray addr = %p \n",NewArray);
printf("*NewArray addr = %p \n",*NewArray);
输出信息:
NewArray addr = 0x0022FE84
*NewArray addr = 0x0022FE84
也就是说二者的数据是相同的, 指向的是同一个内存地址.
这个不难理解.数组都是指向的数组第一个元素的内存地址.
但是二者却不是同一个事物!!!
NewArray = *NewArray ; (通过if(NewArray == *NewArray) 可以再次判断出二者相等)
但是
*NewArray = 0x0022FE84;*(*NewArray) = 1;
呵呵,如果是一个二级指针**p的话,p 和 *p 绝对不是两个相同的值. 数组和指针的不同之处就在这里吧.
2)想在主调函数里像用二维数组一样使用二维数组参数
测试函数:
int Test(int **array)
{
int i,j;
for(i = 0; i<5; i++){
for(j = 0; j < 3; j++){
printf("%d\t",Array[i][j]);
}
printf("\n");
}
return 0;
}
这时候测试函数Test的形参设成 int **array就不行了,
直接报错 Array[i][j] 使用语法错误不能通过.
想起上次报错警告说 int (*)[3] 转换成 int ** ,可以想到二维数组类型是 int (*)[3].
所以要将Test 设成:
int Test(int (*Array)[3])
调用还依旧使用
Test(NewArray);
int (*Array)[3]; 是啥玩意?
先看这个: (让你不再害怕指针中如此说)
int (*p)[3];//首先从P处开始,先与*结合,说明P是一个指针(与"()"这步可以忽略,只是为了改变优先级)
//然后再与[]结合,说明指针所指向的内容是一个数组,
//然后再与int结合,说明数组里的元素是整型的.
//所以P是一个指向由整型数据组成的数组的指针
如果想准确使用二维数组,我们必须让编译器明白这个二维数组的array的"步幅"是多大,要确定是它下次增加1要跳转到哪里去,在这里需要让编译器清楚是数组指针加1,还是整型指针加1.
更多细节有待追究.