在问题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”指针的地址?
答案 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指针开始的常量内存地址。