数组一些模糊概念

数组

例子1:int a[3] = {1,2,3};

先记住几个概念,

(1)数组名代表的是一块内存的名称,即例1中,a代表的是一块内存的名称,这个内存的大小是sizeof(a) = sizeof(int)*3 = 12

(2)数组名不能作为左值,只能作为右值。

左值是指值可以改变的,而右值只能读。a代表的是一块内存的名称,如果作为左值,如a=3,意思是对整块内存区域进行赋值为3,这是不允许的。

数组名作为右值时,代表的是数组的首元素地址。如a作为右值时,代表的是a[0]的地址,即作为右值时a==&a[0]

注:sizeof(a)中的a代表什么呢?代表整块的内存区

(3)&a代表的是数组的首地址,如例子1中,&a代表的是整个数组a的首地址

注:虽然&a与a(作为右值时)是相等的,但其代表的意义是不一样的

实例2:

int a[4] = {1,2,3,4};

int *ptr1 = (int*)(&a+1);

int *ptr2 = (int*)((int)a+1);

printf(“%x,%x”,ptr1[-1],*ptr2);

&a+1:&a数组的首地址,因此&a的类型等同于int [4],因此&a+1 =a数组的首地址+1*sizeof(int[4]),在本例中已经越界了,ptr1[-1]被解释为*(ptr1-1),故等于0x04

a+1:a代表数组第一个元素的首地址,其类型等同于int,因此(a+1)等于首元素地址+1*sizeof(int) = &a[1]

int(a)+1:将首元素地址转为为整型(此时是没有任何类型的,只是整数),例如假设

首元素地址为0x12121212,则int(a)+1 = 0x12121213,取值时需要考虑大小端问题。一般操作系统都是小端模式,因此,本例*ptr2解为0x2000

 

来个二维数组的例子

例3:

int a[3][4] ={{1,2,3,4},{5,6,7,8},{9,10,11,12}}

int *pa = (int*)(&a + 1);

 

printf("%d\n",sizeof(a));

printf("%d\n",*a[0]);

printf("%d\n",a[1][3]);

printf("%d\n",**(a+0));

printf("%d\n",*(*(a+1)+2));

printf("%d\n",**(a + 1));

printf("%d\n",pa[-1]);

说明:

(1)a代表内存空间的名称,故sizeof(a)等于sizeof(int [3][4]) = 3*4*4

(2)a作为右值时,代表的是数组首元素地址,而此时的二维数组可以当做一维数组对待,如int a’[3],a’的每个元素拥有四个子元素。

因此a作为右值代表的是{1,2,3,4}这个子数组的首地址,故(a+1)等同于

首地址+1*sizeof(int [4]) = {5,6,7,8}的首地址

(3)&a作为整个二维数组的首地址,故&a+1=首地址+1*sizeof(a)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值