C语言代码解析:数值指针与数值首元素指针的区别

int main()
{
int a[5]={1,2,3,4,5};
int *ptr1=(int*)(&a+1);
int *ptr2=(int*)((int)a+1);
printf("%x,%x",ptr1[-1],*ptr2);
return 0;
}

第一个输出的是5

a是一个数组名,那么&a表示整个数组的指针,它的值和数组a首元素的地址值一样,但是这个指针指向的内存大小是整个数组的总大小。那么&a+1表示的就是整个数组a最后一个元素的下一个内存单元开始数组指针,再把这个指针转换成int的指针,那么ptrl就指向了数组a最后一个元素之后下一个内存开始的4个字节(int*)内存。

ptr1[-1]被解析成*(ptr1-1),即ptr1往后退4个字节,指向a[4],因此其值为5.

注意:虽然&a与a的值都是数组的首地址,但是&a+1 指向下一个数组的首地址,a+1指向数组下一个元素a[1]的首地址

第二个的输出 在不同的cpu上结果是不一样的

(int)a+1 :将数组a 的首地址转换成int并加1,指向a[0]的第二个字节的地址,然后将这个地址转换成 int * 型赋值给ptr2,也就是说ptr2的值是a[0]第二个字节后的连续四个字节的值。

在 小端存储的CPU (intel这些)上 数组a的内存布局如下:(简单起见, 内存地址这里 从0开始)
00000000 :01 00 00 00 02 00 00 00
00000008 :03 00 00 00 04 00 00 00
00000010 :05 00 00 00
由于a的值 就是00000000 但是对a=a+1 之后 a会变成 00000004,因为加的是1*sizeof(int)个字节,但是把a强制类型转换成int之后就编变成 数值 00000000 了,不在有地址的任何附加属性,对其进行+1 操作也是 纯粹数学上的加1 变成00000001

此时又强制类型转换成(int*) 那么此时指向的内存内容是 00 00 00 02 00 00 00

对其取内容(以%x的方式取,取4个字节) 取出来 是00 00 00 02 ,这个按16进制解释出来就是 2000000

大端存储大同小异:内存布局 00 00 00 01 00 00 00 02
(int*)((int)a+1)之后指向 00 00 01 00 00 00 02

结果便是10000
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值