// 目的: 测试 数组名、指针值、指针变量 的关系 数组
// 测试环境:VC6.0 测试
// 时间: 2011.12.22 spa
// 修改时间 2013-04-15 指针
// 说明:退化 —— C标准规定的转换 io
// 行指针—— 一维数组指针 变量
// 页指针—— 二维数组指针 im
#include<stdio.h> d3
main() 二维数组
{ di
int a0 = 1;
int b1[3] = {2,3,4};
int c2[3][3] = {5,6,7,8,9,10,11,12,13};
int d3[3][3][3] = {14,15,16,17,18,19,20,21,22,
23,24,25,26,27,28,29,30,31,
32,33,34,35,36,37,38,39,40};
int *ap0;
int (*bp1)[3]; // 一维指针变量定义
int (*cp2)[3][3]; // 二维指针变量定义
int (*dp3)[3][3][3]; // 三维指针变量定义
// 一维数组
a0 = b1[1]; // 下标运算符 [] 至关于 *(),即等价于 a0 = *(b+1),b1[1]表示第一个元素, 类型是 int
ap0 = b1; // 一维数组名“退化”成一维数组元素指针,b1 表示第一个元素的指针,类型是 int *
ap0 = (b1+1); // 加1的“步长”是 sizeof(int)
bp1 = &b1; // &b是一维数组指针,表示第一行指针,类型是 int * [3]
bp1 = &b1+1; // 加1的“步长”是 sizeof(int)*3
// 二维数组
bp1 = c2; // 二维数组名“退化”成一维数组指针,类型是 int * [3]
bp1 = (c2+1); // 加1的“步长”是 sizeof(int)*3
ap0 = c2[1]; // 下标运算符 [] 至关于 *(),即等价于 *(c2+1),至关于一维数组名
// 自动“退化”成一维数组元素指针,c2[1]表示类型是第二行第一个元素的指针,类型是 int *
ap0 = c2[1]+1; // 加1的“步长”是 sizeof(int)
bp1 = &c2[1]; // 下标运算符 [] 至关于*(),[] 优先级高于 &,即等价于 &(*(c2+1))取一维数组的地址
// &c2[1]表示第二行行指针,类型是 int * [3]
bp1 = &c2[1]+1; // 加1的“步长”是 sizeof(int)*3
cp2 = &c2; // 取二维数组地址,获得二维数组指针,&c2类型是int * [3][3]
cp2 = &c2+1; // 加1的“步长”是 sizeof(int)*3*3
// 三维数组
cp2 = d3; // 三维数组名“退化”成二维数组指针,类型是 int * [3][3]
bp1 = *d3; // d3进行运算首先“退化”,再进行指针运算,值等价于 一维数组名
ap0 = **d3; // 至关于整形指针,可是不能当作左值,即不能自加
cp2 = d3+1; // 加1的“步长”是 sizeof(int)*3*3
bp1 = d3[1]; // 下标运算符 [] 至关于 *(),即等价于 *(d3+1),至关于二维数组名
// 自动“退化”成一维数组指针,c2[1]表示第二页第一行的行指针,类型是 int *[3]
bp1 = d3[1]+1; // 加1的“步长”是 sizeof(int)*3
cp2 = &d3[1]; // 下标运算符 [] 至关于*(),[] 优先级高于 &,即等价于 &(*(d3+1))取二维数组的地址
// &c2[1] 表示第二页的页指针,类型是 int * [3][3]
cp2 = &d3[1]+1; // 加1的“步长”是 sizeof(int)*3*3
dp3 = &d3; // 取三维数组地址,获得三维数组指针,&d3类型是int * [3][3][3]
dp3 = &d3+1; // 加1的“步长”是 sizeof(int)*3*3*3
printf("%d\n",sizeof(ap0)); // 4 指针变量
printf("%d\n",sizeof(bp1)); // 4 指针变量
printf("%d\n",sizeof(cp2)); // 4 指针变量
printf("%d\n",sizeof(dp3)); // 4 指针变量
printf("%d\n",sizeof(b1)); // 3*4 是一维数组名
printf("%d\n",sizeof(b1+1)); // 4
printf("%d\n",sizeof(c2)); // 3*3*4 是二维数组名
printf("%d\n",sizeof(c2+1)); // 4
printf("%d\n",sizeof(d3)); // 3*3*3*4 是三维数组名
printf("%d\n",sizeof(d3+1)); // 4
printf("%d\n",sizeof(&b1)); // 3*4 一维数组指针
printf("%d\n",sizeof(&b1+1)); // 4
printf("%d\n",sizeof(&c2)); // 3*3*4 二维数组指针
printf("%d\n",sizeof(&c2+1)); // 4
printf("%d\n",sizeof(&d3)); // 3*3*3*4 三维数组指针
printf("%d\n",sizeof(&d3+1)); // 4
printf("%p\n",d3); // 三维数组的第一页,页指针 int *[3][3]
printf("%p\n",d3+1); // 三维数组的第二页,页指针 int *[3][3]
printf("%p\n",&d3); // 三维数组 int *[3][3][3]
printf("%p\n",&d3+1); // 三维数组 int *[3][3][3]
printf("%p\n",*(d3+1)); // 三维数组的第二页第一行,行指针 int * [3]
printf("%p\n",*(d3+1)+1); // 三维数组的第二页第二行,行指针 int * [3]
printf("%p\n",*(*(d3+1)+1)); // 三维数组的第二页第二行第一个元素,整形指针 int *
printf("%p\n",*(*(d3+1)+1)+1); // 三维数组的第二页第二行第二个元素,整形指针 int *
printf("%d\n",*(*(*(d3+1)+1)+1)); // 三维数组的第二页第二行第二个元素 int
// printf("%p\n",d3++); // 数组名不能当左值,故而不能自加
// printf("%p\n",(*d3)++); // * 优先级小于 ++,(*d3)等价于 一维数组名不能当左值,故而不能自加
// printf("%p\n",(**d3)++); // (**d3),等价于数组名不能当左值,故而不能自加
printf("%p\n",(***d3)++); // (***d3) 等价于整形变量
//结论:1.数组名 参加运算(赋值、加减) 会变为 下降一维度 的指针值
// 2.数组名 进行 & 运算,获得 本维度 的指针
// 3.sizeof对数组名进行操做,获得数组大小
// 4.任何类型的指针都是4个字节
}