我编写了一个代码来查找整数数组中的元素数量,如下所示:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int arr[] = {2, 3, 5, 5};
int i;
for(i = 0; i < 4; i++)
{
printf("%d %d\n", &arr[i], arr[i]);
}
printf("%d", &arr[i - 1] - arr);
return 0;
}
最后printf
打印3
而不是4
,这是数组中元素的数量。为什么代码打印的数量少于数组中元素的数量?
答案 0 :(得分:1)
您将错误的格式说明符传递给printf
。因此,您在循环中获得的任何输出都是未定义行为的结果。要正确且便携地打印指针,您必须使用%p
说明符并传递void*
:
printf("%p %d\n", (void*)&arr[i], arr[i]);
最后printf
打印3的原因(即使格式说明符可能再次错误),是因为这是数组中最后一个单元格与开头之间的偏移量。这就是你计算的,所以请记住,最后一个单元格的索引是偏移量3
。
可以在类型ptrdiff_t
中捕获减去两个指针的结果。要打印您需要%td
格式说明符,如果我们要让您的代码再次可移植:
printf("%td", &arr[i-1]-arr);
要计算数组长度,您需要减去指向数组的“一个传递结束”元素的指针(不要担心,计算该地址不是未定义的行为)和指向开头的指针。在循环后将其应用于print语句
printf("%td", (arr + i) - arr);
非常期待,只是i
(4)。
答案 1 :(得分:1)
您的上一次printf
需要更正说明符,因为在您的情况下,第一个和最后一个位置地址的差异可以很容易地适合int
但是caan会产生未定义的行为,因此请使用td
说明符作为区别地址为ptrdiff_t
类型。问题是你如何计算数组的长度,请记住索引是从零完成的,如果你的数组长度为4
,则最后一个索引为3
和
array length according to your code is 3 - 0 = 3
but actually it should be 3 - 0 + 1 = 4
将您的外部printf
更改为
printf("%td",&arr[i-1] - arr + 1);
我希望这会对你有所帮助。您尝试打印地址而不是printf
时,for循环中的int
也需要正确的说明符。