/*
============================================================================
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
#include
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