/* ============================================================================ Name : TeatArr.c Author : lf Version : Copyright : Your copyright notice Description : 二维数组的认识以及其表示元素的两种方式 备注说明 1 要理解二维数组的存储方式. 2 实际上利用a[i][j]的方式并不"正统",这是这靠近我们的 常识一些,更本质和应该是还是利用指针. 参考资料: http://blog.csdn.net/iu_81/article/details/1782642 http://www.jb51.net/article/54220.htm Thank you very much ============================================================================ */ #include <stdio.h> #include <stdlib.h> int main(void) { test1(); test2(); test3(); return EXIT_SUCCESS; } /** * 一维数组的两种表达方式 * int *p=&a * 指针p执行了数组a的首元素. * 又因为*p是取内容,所以*(p+N) * 取的就是第N个元素的内容 */ void test1(){ int a[5]={0,1,2,3,4}; //第一种方式:下标表示法 int i=a[2]; printf("i=%d\n",i); //第二种方式:指针表示 int *p=&a; int j=*(p+2); printf("j=%d\n",j); printf("==========\n"); //在一维数组中数组名就是首元素的地址 //所以a和&a[0]是等值的. //但是注意&a虽然值和它们两个相等,但是它是 //代表整个数组的块地址的起始值. //这点通过sizeof()可以看出来 printf("a=%x,sizeof(*a)=%d\n",a,sizeof(*a)); printf("&a[0]=%x,sizeof(*&a[0])=%d\n",&a[0],sizeof(*&a[0])); printf("&a=%x,sizeof(*&a)=%d\n",&a,sizeof(*&a)); printf("==========\n"); //&a是一个地址,再执行*&a还是得到这个地址.在数值上也等于a printf("&a=%x\n",&a); printf("*&a=%x,sizeof(*(*&a))=%d,a=%x\n",*&a,sizeof(*(*&a)),a); printf("==========\n"); } /** * 二维数组的认识 * * 关于二维数组的指针表示方式,简述如下: * 二维数组的每个元素是一个一维数组. * 比如此处的a[3][4]可以看成是有3个元素的一维 * 数组,每个元素又是具有4个元素的一维数组. * 所以此时可把二维数组a[3][4]看作一维数组a[3] * 这个一维数组有三个元素,每个元素又是一个一维数组. * 在此打印每行的地址: * &a[0]=28feb0 * &a[1]=28fec0 * &a[2]=28fed0 * 可以看到每行的地址相差4*4=16 * 但是为什么 * a[0]=28feb0 * a[1]=28fec0 * a[2]=28fed0 * 也打印出来了每行的地址??? * 这个很简单,在test1()中已经进行了说明: * &a是一个地址,再执行*&a还是得到这个地址. * 即&a[0]=*&a[0]在数值上也等于a * 所以&a[i]与*(&a[i])和a[i]是同一回事!!! * * 因为a是指向第一行的地址,所以a+1代表第二行的地址,a+2代表第三行的地址 * 所以&a[i]与a+i是同一回事!! * * 综上所述: * 在二维数组a中 * &a[i]与*(&a[i])和a[i]还有a+i是等价的 * * 由此可以看到两条演变的路线: * &a[i]-->*&a[i]-->a[i] * &a[i]-->*&a[i]-->*(&a[i])-->*(a+i) * */ void test2(){ int a[3][4] = { { 0, 1, 2, 3 }, { 4, 5, 6, 7 }, { 8, 9, 10, 11 } }; //打印二维数组每一行的首地址.&a[i]与a+i等价 printf("&a[0]=%x,a+0=%x\n",&a[0],a+0); printf("&a[1]=%x,a+1=%x\n",&a[1],a+1); printf("&a[2]=%x,a+2=%x\n",&a[2],a+2); printf("&a[0]=%x,a[0]=%x,*(a+0)=%x\n",&a[0],a[0],*(a+0)); printf("&a[1]=%x,a[1]=%x,*(a+1)=%x\n",&a[1],a[1],*(a+1)); printf("&a[2]=%x,a[2]=%x,*(a+2)=%x\n",&a[2],a[2],*(a+2)); printf("==========\n"); } /** * 二维数组的两种表达方式 * * 利用下标方式访问i行j列的数据很简单:a[i][j] * * 如果用指针的方式又该是怎么样呢? * 第一步:找到行 * 从test2()中我们已经知道了行地址是*(a+i) * 第二步:找到列 * 找到了行再找列就简单多了,偏移j个单位就行 * * 于是地址为*(a+i)+j,取值为*(*(a+i)+j); * */ void test3(){ int a[3][4] = { { 0, 1, 2, 3 }, { 4, 5, 6, 7 }, { 8, 9, 10, 11 } }; //第一种方式:下标表示法 int i=a[2][3]; printf("i=%d\n",i); //第二种方式:指针表示 int j=*(*(a+2)+3); printf("j=%d\n",j); }
原文地址:http://blog.csdn.net/lfdfhl/article/details/43958353