数组与指针

摘自:https://blog.csdn.net/qq_22238021/article/details/79779574

【注意事项】

1、一个一维int数组的数组名实际上是一个int* const p类型,p指向第一个元素; 

2、一个二维int数组的数组名实际上是一个int (*const p)[n],p指向第一行;

3、数组名做参数会退化为指针,除了sizeof,也就是说sizeof(a),返回的是数组大小不是指针大小。

int num =0 ;                       //在32机器中告诉C编译器分配4个字节的内存 
int a [] = {1,3,5,12,6,7,54,32};   //告诉C编译器分配32个字节的内存 	
printf("a:%d ,a+1:%d,&a:%d,&a+1:%d\n",a,a+1,&a,&a+1) ;
	
//a+1 和 &a+1 结果不一样  
//虽然输出结果上面,a和&a一样,但是a和&a所代表的数据类型不一样
	
/*重要*/ 
//a代表的数据首元素的地址(首元素),同时与整个数组地址重合,但其不能代表整个数组,只能代表起始个体的地址 
//&a代表的是整个数组的地址(特别特别的注意),它的+1是以整块数组所占字节数总数为单位+1

输出结果:a:1638176 ,    a+1:1638180,    &a:1638176,    &a+1:1638208

假设有一维数组:

 char a[3]

该数组一共有3个元素,元素的类型为char,如果想定义一个指针指向该数组,也就是如果想把数组名a赋值给一个指针变量,那么该指针变量的类型应该是什么呢?前文说过,一个数组的数组名代表其首元素的首地址,也就是相当于&a[0],而a[0]的类型为char,因此&a[0]类型为char *,因此,可以定义如下的指针变量:

char* p = a;    //相当于char* p = &a[0]

大家都应该知道,a和&a[0]代表的都是数组首元素的首地址,而如果你将&a的值打印出来,会发现该值也等于数组首元素的首地址。请注意这里的措辞,也就是说,&a虽然在数值上也等于数组首元素首地址的值,但是其类型并不是数组首元素首地址类型,也就是char *p = &a是错误的。

对数组名进行取地址操作,其类型为整个数组,因此,&a的类型是char (*)[3],所以正确的赋值方式如下:

char (*p)[3] = &a;

但为什么不能用 char** p=&a 来初始化呢,a[0]的类型是char,&a[0]的类型就是char*。a虽然代表首元素的首地址,但a只是值等于&a[0],a的类型其实是char [3],所以&a的类型就是char (*)[3]!

很多人对类似于a+1、&a+1、&a[0]+1、sizeof(a)、sizeof(&a)等感到迷惑,其实只要搞清楚指针的类型就可以迎刃而解。比如在面对a+1和&a+1的区别时,由于a表示数组首元素首地址,其类型为char *,因此a+1相当于数组首地址值+sizeof(char)即第二个元素的地址(相当于地址+地址里放的东西的sizeof*个数);而&a的类型为char (*)[3],代表整个数组,因此&a+1相当于数组首地址值+sizeof(a)(这里的a就不是地址了,而是代表数组这个东西),也可以理解成地址+sizeof(类型去掉*)*个数

sizeof(a)代表整个数组大小,但无论数组大小如何,sizeof(&a)永远等于一个指针变量占用空间的大小,具体与系统平台有关。

假如有如下二维数组:

char a[3][2];

由于实际上并不存在多维数组,因此,可以将a[3][2]看成是一个具有3个元素的一维数组,只是这三个元素分别又是一个一维数组。实际上,在内存中,该数组的确是按照一维数组的形式存储的,存储顺序为(低地址在前):a[0][0]、a[0][1]、a[1][0]、a[1][1]、a[2][0]、a[2][1]。(此种方式也不是绝对,也有按列优先存储的模式)

为了方便理解,此处画了一张逻辑上的内存图,之所以说是逻辑上的,是因为该图只是便于理解,并不是数组在内存中实际的存储模型(实际模型为前文所述)。

a是第一维数组的数组名,代表首元素首地址,而首元素是一个具有两个char类型元素的一维数组,因此a就是一个指向 具有两个char类型元素数组的数组 的指针,而首元素的类型为char [2],所以a的类型就是char(*)[2]。同理a[0]其实一个一维数组,其第一个元素为a[0][0],类型为char,所以a[0]相当于其第一个元素的地址也就是&a[0][0],其类型为char*,所以可以如下赋值:

char (*p)[2]  = a;    //a为第一维数组的数组名,类型为char (*)[2]
char* p = a[0];    //a[0]为第二维数组的数组名,类型为char *

同样,&a代表整个数组的首地址,而a的类型为数组类型(其实并没有这个类型),也就是char [3][2],所以&a的类型应该为char (*)[3][2],所以应如下赋值:  

char (*p)[3][2] = &a;

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值