二维数组定义:
int arr[2][3];
typedef p arr[3];
p *q;
二维数组在内存中地址存储顺序:
for (size_t i = 0; i < 2; i++)
{
for (size_t j = 0; j < 3; j++)
{
//数组地址线性增长,可能是arr[0][0],arr[0][1]。。。。也可能是arr[0][0],arr[1][0]
//本例是先行后列
printf("value:%d, address:%p\n", tempArr[i][j], &tempArr[i][j]);
}
}
printf("-------------------------\n");
//value:1, address:010FF770
//value:2, address:010FF774
//value:3, address:010FF778
//value:4, address:010FF77C
//value:5, address:010FF780
//value:6, address:010FF784
二维数组做参数:
void address(int (*tempArr)[3])
{
for (int i = 0; i < 2; i++)
{
printf("tempArr:%p\n",tempArr[i]);
printf(("&tempArr:%p\n"), &(tempArr[i]));
for (size_t j = 0; j < 3; j++)
{
printf("value:%d ", tempArr[i][j]);
}
printf("\n");
}
//tempArr:0073FD8C
//&tempArr:0073FD8C
//value : 1 value : 2 value : 3
//tempArr : 0073FD98
//&tempArr : 0073FD98
//value : 4 value : 5 value : 6
}
int main()
{
int arr[2][3] = { { 1,2,3 },{ 4,5,6 } };
address(arr);
system("pause");
return 0;
}
int (*tempArr)[3]此处等同于int tempArr[][3]
int *tempArr[3]为一个一维数组,数组中每个元素都是指针。
为什么参数可以写成int tempArr[][3],而不可以写成int tempArr[2][];
语法上:tempArr理解成一个指针,必须告诉指针指向的类型int [3]。
个人理解:这么写带来一个额外的好处,可以通过传参截取数组任意位置,任意长度的连续元素。如int temp[0+1][3];
tempArr每次+1 步长为指向元素类型的大小,此处为int*3.
关于上段代码中tempArr和&tempArr,地址相同的理解(如果有误,欢迎指出):此处没有额外申请空间,tempArr可以理解成指针,但是没有单独为指针申请空间,本身存储的就是指向元素的地址,即第一组元素首元素地址,和第二组元素首元素地址(有误,待纠正)
区别于上,附上一段指针申请额外空间的代码(此处代码原地址http://blog.csdn.net/zqxnum1/article/details/40592737);
#include <stdio.h>
typedef char p[3];
int main(){
char ch[2][3];
printf("%d\n%d\n%d\n%d\n",&ch,ch[0],&ch[0],&ch[0][0]);
printf("\n");
p *q = new p[2];
printf("%d\n%d\n%d\n%d\n",&q,q[0],&q[0],&q[0][0]);
return 0;
}
输出结果如下:
q 本质上还是个指针,是个变量,它自身位于栈区,但是它的内容是某个二维数组的地址,换言之,它的内容与 ch 等价, 但是 q 不是 ch, 这就是编译器对待指针形式的数组与 直接形式的数组的不同之处, q 作为一个变量,自身也要存在内存的某个位置,而符号“q”就是这个位置的代号,而 ch 直接就是某块内存的首地址的代号。