有C语言的大佬么,求大佬解答一下这个基础问题。

有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 并没有转化成数组长度 只是凑巧了