有C语言的大佬么,求大佬解答一下这个基础问题。
#include<stdio.h>
void main( void ) {
int a[5]={1,2,3,4,5};
int *ptr=(int *)(&a+1);
printf("%d,%d",*(a+1),*(ptr-1));
return;
}
&a+1 为什么等于 a+(sizeof(a)/sizeof(a[1))
首先要明确C语言的地址不是简单的相加
比如在地址总线为32位的环境下,定义int a[5] = {1, 2, 3, 4, 5};
假设数组a的地址为0x00000000,那么
a[0]的地址为0x00000000
a[1]的地址为0x00000004
a[2]的地址为0x00000008
a[3]的地址为0x0000000C
a[4]的地址为0x00000010
虽然a和a[0]在数值上相同,但是实际意义是不同的,
&a是表示数据类型为int[5]的地址, 该地址指向整个数组,大小为20字节,
&a[0]是表示数据类型为int的地址, 该地址指向数组的一个元素,大小为4字节
所以
&a+1 = 0x00000000 + 0x00000014 = 0x00000014
&a[0]+1 = 0x00000000 + 0x00000004 = 0x00000004
(int*)&a, 是把int[5]*强制转化为int*,此时表示该地址的数据类型为int
然后在+1, 即为+四个字节
(int*)&a + 1 = 0x00000000 + 0x00000004 = 0x00000004
&a+1 等于 数组a加上一个数组a的长度 等于 a[0]+5 等于 a[5]这个不存在的位置
sizeof(a[1]]) 等于4
sizeof(a)等于20
(sizeof(a)/sizeof(a[1]])) 等于5
a+(sizeof(a)/sizeof(a[1]])) 等于 a+5 等于 a[5]
&a+1 才是重点
&a 这个+1 加的是数组a的长度 a的长度等于5 所以等于a+5 等于a[5]
a+1 等于 a[1]
&a+1 等于 a+数组长度 等于 a[数组长度] 的那个位置的地址
我很好奇的是 &a+1 为什么会转换为了数组长度 那么&a+2会怎么样呢?
int *ptr=(int *)(&a+1);
ptr 指向 a[5] 这个地址 (ptr等于 &a[5]) *ptr 等于a[5]
ptr-1 等于 ptr 减去1个指针的长度 4个字节(一个int 等于4个字节) 相当于 &a[4]
*(ptr-1) 等于 *(&a[4]) 等于 a[4] a[5]={1,2,3,4,5}; 也就是等于5
&a+2 等于a[10]这个位置的地址
a[5] a[10]这个地址你没有权限 如果使用 会用到别人的数据 可能会报错也可能不会
哈哈,不管了。就这样记好了。知道怎么回事
&a 是数组指针
我给你看一下 地址 0x00cffe58 对应 13631064
地址 0x00cffe6c 对应 13631084
地址0x00cffe68 对应 13631080
很显然 &a+1 移动了5个int
指针指向数组时 指向数组的首地址
为什么ptr - 1 等于5
因为 (&a+1)移动了5个int,然后又强制转换成int 指针
又向前移动了一位
其实ptr 先指向->a[0+5] 后指向a->[0+5-1]
&a+1 并没有转化成数组长度 只是凑巧了