/*============================================================================Name        : TeatArr.cAuthor      : lfVersion     :Copyright   : Your copyright noticeDescription : 二维数组的认识以及其表示元素的两种方式备注说明1 要理解二维数组的存储方式.2 实际上利用a[i][j]的方式并不"正统",但这靠近我们的常识一些,更本质和应该的还是利用指针和数组名.一个二维数组,比如:int array[3][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };它在内存中存在方式如下:0X00F8FE4C    1    2    3    40X00F8FE5C    5    6    7    80X00F8FE6C    9   10   11   12即:从0X00F8FE4C地址开始存放了 1 2 3 4从0X00F8FE5C地址开始存放了5 6 7 8从0X00F8FE6C地址开始存放了9 10 11 12参考资料:http://blog.csdn.net/iu_81/article/details/1782642http://www.jb51.net/article/54220.htmThank you very much============================================================================*/#include <stdio.h>
#include <stdlib.h>int main(void) {
//  test0();
//  test1();test2();
//  test3();return EXIT_SUCCESS;
}/*** 一维数组的两种表达方式* int *p=&a* 指针p执行了数组a的首元素.* 又因为*p是取内容,所以*(p+N)* 取的就是第N个元素的内容*/
void test0(){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[3][4]看作一维数组a[3]* 一维数组a[3]中每个元素又是一个一维数组.* 那么&a[i]表示某一行的地址块的首地址* 所以sizeof(*&a[0])=4*4=16* 即sizeof(a[0])=4*4=16* &a[i]是个地址,所以sizeof(&a[0])=4或者8字节** 在一维数组:* int c[3]={0,1,2};* 中数组名c就是第一个元素的首地址,所以*c=0即取出了第一个元素.* 同样的道理a[i]也是一个一维数组,那么*a[i]就是取出了第i行的* 第一个元素.比如*a[0]=0*/
void test1() {int i=9527;int *p=&i;//p=8d49c90c,&p=8d49c900,*&p=8d49c90c,*p=9527//p是p指向的内存单元,&p是p本身的内存单元,//*&p取出p中所指向的内存单元就是p(和第一个值一样)//*p取出指针指向的内存单元的值printf("p=%x,&p=%x,*&p=%x,*p=%d%x\n",p,&p,*&p,*p);int c[3]={0,1,2};//*c=0,c=8d49c8f0,&c=8d49c8f0,*&c=8d49c8f0//*c好理解,取出了数组中的第一个元素//c是数组第一个元素的首地址,这个也好理解//&c是整个数组的地址块的首地址.//*&c是什么意思呢?//我们习惯简单地说:由于*和&抵消了,所以*&c就是c.//从数值上看也确实是这样.//*&c还可以怎么理解呢?//注意上面的例子://int i=9527;//int *p=&i;//*&p的值就是p,即*&p的值和p是一样的.//其实此处是非常相似的,可以这么看://int *p=&c;//就是说把c的地址保存在了p那个内存单元里面//那么*&p和p是一样的均为整个数组c的地址块的首地址//所以*&c可以这么理解://第一步:&c取出了c的地址放到了某个内存单元里面//第二步:*&c即从某个内存单元里取值,取出的值当然是c的地址//这个过程和上面是一样的.只是没有用一个指针变量明确存放c的地址而已printf("*c=%d,c=%x,&c=%x,*&c=%x\n",*c,c,&c,*&c);printf("===========\n");int a[3][4] = { { 0, 1, 2, 3 },{ 4, 5, 6, 7 },{ 8, 9, 10, 11 } };//&a[0]和a[0]的数值相等,但是含义不同.//&a[0]是整个行的块地址的起始地址//a[0]是这行第一个元素的首地址//*a[0]取得了这行的第一个元素的值//这里把a[0]看做一个一维数组就很好理解了.printf("&a[0]=%x,a[0]=%x,*a[0]=%d\n",&a[0],a[0],*a[0]);printf("sizeof(*&a[0])=%d,,sizeof(a[0])=%d,sizeof(&a[0])=%d,sizeof(*a[0])=%d\n",sizeof(*&a[0]),sizeof(a[0]),sizeof(&a[0]),sizeof(*a[0]));printf("===========\n");}/*** 二维数组的认识** 关于二维数组的指针表示方式,简述如下:* 二维数组的每个元素是一个一维数组.* 这个是认识和分析二维数组的基础和核心** 一个二维数组,比如:* int array[3][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };* 它在内存中存在方式如下:* 0X00F8FE4C    1    2    3    4* 0X00F8FE5C    5    6    7    8* 0X00F8FE6C    9   10   11   12* 即:* 从0X00F8FE4C地址开始存放了 1 2 3 4* 从0X00F8FE5C地址开始存放了5 6 7 8* 从0X00F8FE6C地址开始存放了9 10 11 12* 从本质上而言二维数组的元素在内存中还是线性地按序存放的.** 把二维数组a[3][4]可以看成是有3个元素的一维数组a[3]:* {0X00F8FE4C,0X00F8FE5C,0X00F8FE6C}* 注意的问题:* 0 这个一维数组a[3]是抽象的,不是很具体* 1 a[3]每个元素都是一个行地址.*   a[3]每个元素的值就是每行即每个一维数组的首地址.* 2 这个数组的首地址就是0X00F8FE4C!!!!!*   同理第2个元素的地址就是0X00F8FE5C,其值也是这个值.* 3 二维数组a[3][4]看成是有3个元素的一维数组a[3].*   这里的行数为3得到了体现,那么列数4在哪里体现的呢?*   这个a[3]的步长为4个整型长度即16字节.*   比如int b[3]={0,1,2};*   因为它每个元素都是int类型的,所以它的步长就是4个字节*   b代表第一个元素的地址,b+1代表了第二个元素的地址;*   从b到b+1移动了4个字节.*   所以这里的a[0]到a[1]移动了4*4=16个字节*** 利用下标表示法:* 每个元素的地址用下标表示法为&a[i]其值是*&a[i]即a[i]** 利用指针表示法(数组名表示法):* 每个元素的地址表示为a+i,其值为*(a+i)** 所以可以说:* &a[i]与a+i等价* a[i]与*(a+i)等价** 这只是两种不同表达方式的差异罢了,获取到的值当然是一样的.* 这两种方式即a[i]和*(a+i)都获取到了a[3]每个元素的值* 也是每个一维数组的起始地址.** 小结:* 获取每个一维数组里第j个元素的地址的两种方式就分别是:* a[i]+j和*(a+i)+j* 获取每个一维数组里第j个元素的内容的两种方式就分别是:* *(a[i]+j)和*(*(a+i)+j)* 所以可以说:* a[i]+j和*(a+i)+j等价,都是用来取地址的* *(a[i]+j)和*(*(a+i)+j)等价,都是用来取内容的** 最后,再次提醒a[3]每个元素的地址及其内容是一样的.*/
void test2(){int a[3][4] = { { 0, 1, 2, 3 },{ 4, 5, 6, 7 },{ 8, 9, 10, 11 } };//获取a[3]每个元素地址和其对应的内容的两种方式://&a[i],a[i]和a+i,*(a+i)printf("&a[0]=%x,a[0]=%x <==> a+0=%x,*(a+0)=%x\n",&a[0],a[0],a+0,*(a+0));printf("&a[1]=%x,a[1]=%x <==> a+1=%x,*(a+1)=%x\n",&a[1],a[1],a+1,*(a+1));printf("&a[2]=%x,a[2]=%x <==> a+2=%x,*(a+2)=%x\n",&a[2],a[2],a+2,*(a+2));printf("==========\n");//访问第二行的第三个元素:printf("a[1]+2=%x,*(a[1]+2)=%d\n",a[1]+2,*(a[1]+2));printf("*(a+1)+2=%x,*(*(a+1)+2)=%d\n",*(a+1)+2,*(*(a+1)+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);
}///**
// * 这是以前我土鳖的认识方法。。。
// * 也就不删了。。。
// *
// *
// * 二维数组的认识
// *
// * 关于二维数组的指针表示方式,简述如下:
// * 二维数组的每个元素是一个一维数组.
// * 比如此处的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");
//}//**
// * 这是以前我土鳖的认识方法。。。
// * 也就不删了。。。
// * 二维数组的认识
// *
// * 关于二维数组的指针表示方式,简述如下:
// * 二维数组的每个元素是一个一维数组.
// * 这个是认识和分析二维数组的基础和核心
// *
// * 一个二维数组,比如:
// * int array[3][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
// * 它在内存中存在方式如下:
// * 0X00F8FE4C    1    2    3    4
// * 0X00F8FE5C    5    6    7    8
// * 0X00F8FE6C    9   10   11   12
// * 即:
// * 从0X00F8FE4C地址开始存放了 1 2 3 4
// * 从0X00F8FE5C地址开始存放了5 6 7 8
// * 从0X00F8FE6C地址开始存放了9 10 11 12
// *
// * 把二维数组a[3][4]可以看成是有3个元素的一维数组a[3]
// * 利用下标表示法:每个元素的地址用下标表示法为&a[i]其值是*&a[i]即a[i]
// * 利用指针表示法(数组名表示法):每个元素的地址表示为a+i,其值为*(a+i)
// * 所以可以说:
// * &a[i]与a+i等价
// * a[i]与*(a+i)等价
// * 这只是两种不同表达方式的差异罢了,获取到的值当然是一样的.
// * 这两种方式即a[i]和*(a+i)都获取到了a[3]每个元素的值
// * 也是每个一维数组的起始地址
// *
// * 每个元素的地址用下标表示法为&a[i]其值是*&a[i]即a[i]
// * 我们可以发现&a[i]和a[i]在数值上是相等的.
// * 这是为什么呢?可以这么理解:
// * 还是要从二维数组的本质说起:
// * 1 二维数组的每个元素是个一维数组
// * 2 把二维数组a[i][j]可以看成是有i个元素的一维数组a[i]
// *   那么a[0],a[1]....a[i]都是一维数组
// * 既然a[i]是一维数组,那么&a[i]是一维数组地址块的首地址
// * a[i]是一维数组第一个元素的首地址.
// * 所以他们在数值上是相等的,但是含义不同.
// *
// * 每个元素的地址表示用指针和数组名表示为a+i,其值为*(a+i)
// * 我们可以发现a+i和*(a+i)在数值上是相等的
// * int array[3][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
// * 它在内存中存在方式如下:
// * 0X00F8FE4C    1    2    3    4
// * 0X00F8FE5C    5    6    7    8
// * 0X00F8FE6C    9   10   11   12
// * 可以明确的一点:这一块内存地址是连续的,即每个元素之间也是紧挨着存放的.
// * 那么a[3]可以看成{0X00F8FE4C,0X00F8FE5C,0X00F8FE6C}
// * 当然这个数组的首地址也就是0X00F8FE4C
// * a+i表示第i个元素的地址.
// * *(a+i)是其对应的值
// *
// *
// * 那么获取每个一维数组里第j个元素的地址的两种方式就分别是:
// * a[i]+j和*(a+i)+j
// * 那么获取每个一维数组里第j个元素的内容的两种方式就分别是:
// * *(a[i]+j)和*(*(a+i)+j)
// * 所以可以说:
// * a[i]+j和*(a+i)+j等价
// * *(a[i]+j)和*(*(a+i)+j)等价
// */
//void test2(){
//
//  int i=9527;
//  int *p=&i;
//  printf("&i=%x,p=%x,&p=%d\n",&i,&(*p),*p);
//
//  int a[3][4] = { { 0, 1, 2, 3 },
//                  { 4, 5, 6, 7 },
//                  { 8, 9, 10, 11 } };
//
//  //获取a[3]每个元素地址和其对应的内容的两种方式:
//  //&a[i],a[i]和a+i,*(a+i)
//  printf("&a[0]=%x,a[0]=%x <==> a+0=%x,*(a+0)=%x\n",&a[0],a[0],a+0,*(a+0));
//  printf("&a[1]=%x,a[1]=%x <==> a+1=%x,*(a+1)=%x\n",&a[1],a[1],a+1,*(a+1));
//  printf("&a[2]=%x,a[2]=%x <==> a+2=%x,*(a+2)=%x\n",&a[2],a[2],a+2,*(a+2));
//  printf("==========\n");
//
//  //访问第二行的第三个元素:
//  printf("a[1]+2=%x,*(a[1]+2)=%d\n",a[1]+2,*(a[1]+2));
//  printf("*(a+1)+2=%x,*(*(a+1)+2)=%d\n",*(a+1)+2,*(*(a+1)+2));
//
//  printf("==========\n");
//}

二维数组的认识及其表示元素的两种方式相关推荐

  1. C语言学习之利用指针输出二维数组任一行任一列元素的值

    利用指针输出二维数组任一行任一列元素的值. int main(){int a[3][4];int i,j,x,y;int (*p)[4];//指针变量p指向包含4个整型元素的一维数组printf(&q ...

  2. 13.请编一个函数void fun(int tt[M][N],int pp[N]),tt指向一个M行N列的二维数组,求出二维数组每列中最小元素,并依次放入pp所指一维数组中。

    13.请编一个函数void fun(int tt[M][N],int pp[N]),tt指向一个M行N列的二维数组,求出二维数组每列中最小元素,并依次放入pp所指一维数组中.二维数组中的数已在主函数中 ...

  3. 请编写一个函数void fun(int tt[M][N],int pp[N]),tt指向一个M行N列的二维数组,求出二维数组每列中最小元素,并依次放入pp所指一维数组中。

    #include <iostream> #include<iomanip> using namespace std; #define M 3 #define N 4 /*求出二 ...

  4. C语言编程>第七周 ⑧ 请编一个函数void fun(int a[M][N],int b[N]),c指向一个M行N列的二维数组,求出二维数组每列中最大元素,并依次放入b所指一维数组中。

    例题:请编一个函数void fun(int a[M][N],int b[N]),c指向一个M行N列的二维数组,求出二维数组每列中最大元素,并依次放入b所指一维数组中.二维数组中的数己在主函数中赋予. ...

  5. java二维数组元素_java二维数组,获取整行元素详解

    之前给大家讲过java二维数组获取单个元素方面的知识,下面的话就来给大家讲一下java二维数组获取整行元素方面的知识. 除去获取单个元素和全部元素之外,还可以单独获取二维数组的某一行中所有元素的值,或 ...

  6. python键盘输入数组_python 二维数组切割Python读取键盘输入的2种方法

    Python提供了两个内置函数从标准输入读入一行文本,默认的标准输入是键盘.如下: 1.raw_input 2.input raw_input函数raw_input() 函数从标准输入读取一个行,并返 ...

  7. python二维数组换行输出_python 二维数组切割Python读取键盘输入的2种方法

    Python提供了两个内置函数从标准输入读入一行文本,默认的标准输入是键盘.如下: 1.raw_input 2.input raw_input函数raw_input() 函数从标准输入读取一个行,并返 ...

  8. PHP实现对多维数组按照某个键值排序的两种解决方法

    实现对多维数组按照某个键值排序的两种解决方法(array_multisort和array_sort): 第一种: array_multisort()函数对多个数组或多维数组进行排序. //对数组$ho ...

  9. java中byte数组与int类型的转换(两种方式)

    java中byte数组与int类型的转换,在网络编程中这个算法是最基本的算法,我们都知道,在socket传输中,发送.者接收的数据都是 byte数组,但是int类型是4个byte组成的,如何把一个整形 ...

最新文章

  1. 自定义RadioGrop,支持添加包裹着的RadioButton
  2. sdut 3346 sdut 3344 Runtime Error Runtime Error?
  3. STM32 KEIL 串口打印printf使用详解
  4. Android之HandlerThread源码分析和简单使用(主线程和子线程通信、子线程和子线程通信)
  5. Java : Hibernate 动态+分页+自定义字段+自定义实体类查询
  6. 2021中国企服企业规模化获客体系建设指南
  7. 【零基础学Java】—哈希值(四十一)
  8. ad软件侵权律师函_专业版,无AD无限制,建议收藏~
  9. Azure平台跨存储迁移虚拟机
  10. 2. 通用基础技术框架搭建
  11. TCP新手误区–数据校验的意义
  12. sql 取一个月日期去掉周末的所有日期_LeetCode:SQL
  13. 2018年秋季学期课表
  14. html5 几何酷站,10个值得学习的HTML5+CSS3视觉特效酷站欣赏
  15. php判断支付宝,PHP怎样判断是否为支付宝客户端
  16. Rundll32.exe 如何运行dll中的函数
  17. 数据预处理(一):无量纲化
  18. 800-C++ throw(抛出异常)详解
  19. myeclipse7.5注册码
  20. Mysql的数据类型和字段类型详解

热门文章

  1. Blender图解教程:给苏珊一头美腻的秀发 之 用粒子实现写实风头发
  2. Matlab:常见涡旋光束仿真
  3. Latex常用语法结构
  4. 2023年产品经理需要考的证书——NPDP,含金量高,666
  5. 44 - 操作MySQL数据库
  6. 分布式发号器架构设计
  7. C++语言程序设计第五版 - 郑莉(第四章课后习题)
  8. js通过class获取元素
  9. 联想推出专为边缘和数据密集型工作负载而设计的单插槽服务器
  10. 【机器学习】Kmeans聚类(含代码)