用于打印数组中元素的代码的代码少于元素的数量

时间:2017-01-29 14:06:14

标签: c pointers

我编写了一个代码来查找整数数组中的元素数量,如下所示:

#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,这是数组中元素的数量。为什么代码打印的数量少于数组中元素的数量?

2 个答案:

答案 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也需要正确的说明符。