指针的值在for循环内外是不同的

时间:2014-11-18 12:18:16

标签: c pointers

我正在玩C中的指针,我似乎无法理解我得到的结果。

查看最后一次迭代&循环后的print语句,为什么我在for循环内外得到不同的值?

#include <stdio.h>

int main(void)
{
    int *ptr;
    int a1[] = {2, 5, 4, -1};
    ptr = &a1[0];

    for (int i = 0; i < 4; i++)
    {
        printf("######## ITERATION %d ########\n", i);
        printf("a1[%d] = %d. \n", i, a1[i]);
        printf("Current location - %ld \n", ptr);
        ptr = ptr + 1;
        printf("Next value would be - a1[%d] = %d at location - %ld\n\n\n", i+1, *ptr, ptr);
    }
    printf("%ld - %d\n", ptr, *(ptr));
}

这将是输出 -

*** ITERATION 0 ***
a1[0] = 2.
Current location - 2686728
Next value would be - a1[1] = 5 at location - 2686732

*** ITERATION 1 ***
a1[1] = 5.
Current location - 2686732
Next value would be - a1[2] = 4 at location - 2686736

*** ITERATION 2 ***
a1[2] = 4.
Current location - 2686736
Next value would be - a1[3] = -1 at location - 2686740

*** ITERATION 3 ***
a1[3] = -1.
Current location - 2686740
Next value would be - a1[4] = 3 at location - 2686744

2686744 - 4

看看我从上一次迭代中获得了什么 - 位置是 2686744 ,值是 3 ,并且一旦我在for循环中进行相同的打印OUTSIDE,它具有值4,对于相同的地址 ...

这导致了2个问题 -

  1. 这个价值甚至来自哪里?在2686740之后显然没有任何东西。阵列结束的地方......
  2. 为什么2686744在循环内部和外部打印时有不同的值?
  3. 提前致谢!

6 个答案:

答案 0 :(得分:8)

首先,使用%p打印指针。然后,在最后一次迭代中(在递增a[4]之后)访问数组的第5个元素(ptr)时,代码中存在未定义的行为。这就是你获得不同价值的原因。

答案 1 :(得分:5)

可能您正在查看存储循环变量i的内存位置(当时值为3)。请注意,从而进入未定义行为的领域。您不能访问数组边界之外的内存。

循环结束后,该位置的变量(以前存在)再次增加。因此,您发现了4。请注意,这也是未定义的行为。您不能访问属于超出范围的对象的内存区域。

简而言之,任何事情都可能发生。请注意,当您做错事时,您的程序不需要崩溃,甚至不要警告您。并非所有看似有用的都是有效的代码。在这个意义上,我建议,还要重新审视documentation of the printf()函数并尝试理解各种格式说明符,特别是对于指针和不同大小的整数。

答案 2 :(得分:1)

对于每个循环,首先打印然后增加指针。因此,在循环中最后一次运行之后,打印数组的第4项,然后增加指针越界,指向不存在的第5项。这是未定义的行为,因此任何事情都可能发生,包括打印垃圾值。

答案 3 :(得分:1)

嗯,首先,从4个阵列的数组中,你打印的是第五个位置的内容......这意味着价值是“垃圾”,就是说,这个价值根本就没有意义。请记住,数组的最后一个位置总是n-1,其中n是数组的大小(它的元素数),第一个位置是0.

答案 4 :(得分:0)

访问数组越界。使用%p打印指针。 你的数组包含4个元素,所以你不应该访问a [4],这是数组越界访问。该数组的数组索引是0-3。当你结束for循环时,你的指针将指向一些不在数组中的内存,因此在完成循环后打印它的值是没有意义的。

检查以下代码:

#include <stdio.h>

int main(void)
{
    int *ptr;
    int i;
    int a1[] = {2, 5, 4, -1};
    ptr = &a1[0];

    for ( i = 0; i < 4; i++)
    {
        printf("######## ITERATION %d ########\n", i);
        printf("a1[%d] = %d. \n", i, a1[i]);
        printf("Current location - %p \n", ptr);
        ptr = ptr + 1;
        if(i != 3) 
        printf("Next value would be - a1[%d] = %d at location - %p\n\n\n", i+1, *ptr, ptr);
    }

}

答案 5 :(得分:0)

由于a[4]指向并且不属于数组的地址,因此它将成为程序的另一个变量,是另一个程序或垃圾的变量(用于其他程序且未使用的数据)其实)。 它看起来是i的值,但你不能被嘲笑,也许属于另一个程序的数据已经在你最后两次打印之间实现了。