若有二维数组a:
char a[10][10] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
则a表示二维数组本身,含有100个元素,也可认为含有10个一维数组,每个一维数组含有10个元素,其占有100字节;a[0]表示二维数组a的第一个一维数组,含有10个元素,其占有10字节;a[1]表示二维数组a的第二个一维数组,含有10个元素,其占有10字节;a[0][0]表示二维数组a的第一个元素,同时也是一维数组a[0]的第一个元素,其占有1字节;a[1][0]表示二维数组a的第十一个元素,同时也是一维数组a[1]的第一个元素,其占有1字节。
/**
*二维数组地址,行地址,元素地址及对应的字节数(即这个地址标记的存储片段大小)
*/
printf("二维数组:a地址:%p ;a字节数:%d\n",&a,sizeof(a));
printf("二维数组首行:a[0]地址:%p ;a[0]字节数:%d\n",&a[0],sizeof(a[0]));
printf("二维数组次行:a[1]地址:%p ;a[1]字节数:%d\n",&a[1],sizeof(a[1]));
printf("二维数组首元素:a[0][0]地址:%p ;a[0][0]字节数:%d\n",&a[0][0],sizeof(a[0][0]));
printf("二维数组次元素:a[0][1]地址:%p ;a[0][1]字节数:%d\n\n",&a[0][1],sizeof(a[0][1]));[1]));
运行结果:
可以发现,a地址、a[0]地址和a[0][0]地址相同。其实,在C语言中,数组的地址用其首元素的地址表示,故a[0]的地址就是a[0][0]的地址,a的地址就是a[0]的地址;且在C语言中,用a来表示二维数组a的地址,用a[0]来表示二维数组a的第一个一维数组a[0]的地址;同理,a[1]的地址等于a[1][0]的地址,用a[1]来表示二维数组a的第二个一维数组a[1]的地址。当然,虽然地址一样,其意义并不一样,如在前文中a的字节数,a[0]的字节数,a[0][0]的字节数并不相同。
/**
*数组的地址等于其首元素的地址
*/
printf("二维数组:a地址:%p ;a值: %p\n",&a,a);
printf("二维数组首行:a[0]地址:%p ;a[0]值: %p\n",&a[0],a[0]);
printf("二维数组次行:a[1]地址:%p ;a[1]值: %p\n",&a[1],a[1]);
printf("二维数组首元素:a[0][0]地址:%p ;a[0][0]值: %d\n",&a[0][0],a[0][0]);
printf("二维数组次元素:a[0][1]地址:%p ;a[0][1]值: %d\n",&a[0][1],a[0][1]);
printf("二维数组次行首元素:a[1][0]地址:%p ;a[1][0]值: %d\n\n",&a[1][0],a[1][0]);
运行结果:
取地址运算符&的结果是一个指针,占用固定字节的存储空间
/**
*取地址运算符的结果是一个指针,占用固定字节的存储空间
*/
printf("&a值 :%p ; &a字节数:%d\na值:%p ; a字节数:%d\n\n",&a,sizeof(&a),a,sizeof(a));
运行结果:
在数组中灵活运用*运算符和[]运算符
/**
*灵活运用*运算符和[]运算符
*/
printf("*a值:%p ; *a字节数:%d\n",*a,sizeof(*a));
printf("a[0]值:%p ; a[0]字节数:%d\n",a[0],sizeof(a[0]));
printf("**a值:%d ; *a字节数:%d\n",**a,sizeof(**a));
printf("a[0][0]值:%d ; a[0][0]字节数:%d\n",a[0][0],sizeof(a[0][0]));
printf("*a[0]值:%d ; *a[0]字节数:%d\n\n",*a[0],sizeof(*a[0]));
运行结果:
可以见到,*a没到数组元素维度,值是地址(一维数组a[0]),**a到了数组元素维度,值是存储的数据。
地址运算的结果是指针。a+1指“一维数组”a的第二个元素的地址(此时a中的元素被认为是一维数组),即一维数组a[1]的地址,其本身是一个指针;*(a+1)等同于a[1];*(a+1)+1即元素a[1][1]的地址,其本身是一个指针;*(*(a+1)+1)等同于a[1][1]。
/**
*地址运算的结果是指针
*/
printf("a+1值:%p ; a+1字节数:%d ;a[1]地址:%p\n",a+1,sizeof(a+1),&a[1]);
printf("*(a+1)值:%p ; *(a+1)字节数:%d\n",*(a+1),sizeof(*(a+1)));
printf("a[1]值:%p ; a[1]字节数:%d\n",a[1],sizeof(a[1]));
printf("*(a+1)+1值:%p ; *(a+1)+1字节数:%d ;a[1][1]地址:%p\n",*(a+1)+1,sizeof(*(a+1)+1),&a[1][1]);
printf("*(*(a+1)+1)值:%d ; *(*(a+1)+1)字节数:%d\n",*(*(a+1)+1),sizeof(*(*(a+1)+1)));
printf("a[1][1]值:%d ; a[1][1]字节数:%d\n",a[1][1],sizeof(a[1][1]));
运行结果: