为什么不能将c指针视为数组?

时间:2015-09-15 06:24:56

标签: c arrays

在问题Find size of array without using sizeof in C中,提问者通过获取地址然后指定数组索引为1来处理类似于int数组的int数组:

int arr[100];
printf ("%d\n", (&arr)[1] - arr);

该值最终成为arr之后的100个元素的“下一个”数组中第一个元素的地址。当我尝试这个类似的代码时,似乎没有做同样的事情:

int *y = NULL;
printf("y = %d\n", y);
printf("(&y)[0] = %d\n", (&y)[0]);
printf("(&y)[1] = %d\n", (&y)[1]);

我最终得到了:

y = 1552652636
(&y)[0] = 1552652636
(&y)[1] = 0

(&y)[1]之后为什么y不是指向int的“next”指针的地址?

3 个答案:

答案 0 :(得分:8)

下面:

printf("(&y)[1] = %d\n", (&y)[1]);

你先说:y的地址。然后你说:添加1倍于指向的东西的大小 - 这是指向int的指针,因此可能添加4个字节 - 并取消引用该地址上的任何内容。但是你不知道新的内存地址是什么,你不能/不应该访问它。

答案 1 :(得分:2)

数组不是指针,指针不是数组。

"数组大小" code计算两个数组之间的距离,这个数组将是数组的大小 您的代码尝试计算两个指针之间的距离,这应该是指针的大小。

我认为混淆的根源是(&y)[1]是" next"的。在int之后指向y的指针,而不是其地址。

其地址为&y + 1

以同样的方式,y地址&y,而(&y)[0] - 或等效*(&y) - 为{{1 ' s

(在"数组大小"代码中,y也是" next" ,但由于此值是数组,它被隐式转换为指向数组的第一个元素 - (&arr)[1]的指针。)

如果你运行:

&((&array)[1])[0]

输出看起来像这样:

int *y = NULL;
printf("y = %p\n", y);
printf("&y = %p\n", &y + 0);
printf("&y + 1 = %p\n", &y + 1);

和0xbf867190 - 0xbf86718c = 4,这对于32位指针是有意义的。

访问y = (nil) &y = 0xbf86718c &y + 1 = 0xbf867190 (即(&y)[1])未定义,可能会导致一些随机垃圾。

答案 2 :(得分:0)

感谢您的回答,我认为回答问题的最简单方法是了解每个表达式的价值。首先我们必须知道类型,然后我们可以确定值

我使用c编译器通过将值分配给错误的类型(char)来生成警告,因此我可以确切地看到它认为类型是什么。

鉴于声明int arr[100](&arr)[1]的类型为int [100]

鉴于声明int *ptr(&ptr)[1]的类型为int *

int[100]的值是数组开始的常量内存地址。我不知道为什么这就是历史的所有历史。

另一方面,int *的值是指针当时正在保持的任何内存地址。

所以他们是非常不同的东西。要获取指针开始位置的常量内存地址,必须取消引用它。所以&(&ptr)[1]int **,它是int指针开始的常量内存地址。