gpt4 book ai didi

c - 指针运算;最初必须做两次

转载 作者:太空宇宙 更新时间:2023-11-04 01:25:58 25 4
gpt4 key购买 nike

我这里有一段代码让我有点困惑。似乎如果我使用:p = &j,它需要两个增量才能开始遍历 a[]:

#include <stdio.h>

int main(void) {
int a[4] = {5,2,6,4};
int j = a[0];
int *p;

p = &j;

printf("*p = %d\n", *p);
printf("a[0] = %d\n", a[0]);
printf("address of a[0] = %p\n", &a[0]);

printf("\np++\n\n");
p++;

printf("*p = %d\n", *p);
printf("a[1] = %d\n", a[1]);
printf("address of a[1] = %p\n", &a[1]);

printf("\np++\n\n");
p++;

printf("*p = %d\n", *p);
printf("a[2] = %d\n", a[2]);
printf("address of a[2] = %p\n", &a[2]);

return 0;
}

如果我使用 p = &a[0],那么它工作正常。为什么当我使用&j时,它需要两个p++才能启动。在开始递增数组之前,您可以看到 *p = 5 两次。为什么是这样?任何帮助将不胜感激。

最佳答案

这是一个非常酷的错误,特别是对于刚开始学习 C 的人来说。了解这种看似奇怪的行为将大大提高您对程序工作方式的理解。

您的代码无法正常工作,因为 int ja[0] 没有相同的地址,也就是说 &j != &a [0].

让我用一张图来解释为什么。

所有局部变量a[]、j、p 等... 都分配在程序的call stack 上。 .

因此,在您的示例中,堆栈可能假设如下所示:

enter image description here

从这个非常有艺术感的图中可以看出,a的地址是0x1004,而j的地址计算结果为 0x1000

仅仅因为 2 个变量具有相同的值并不意味着它们将具有相同的内存地址。这就是这里发生的事情。您将 a[0] 的 赋予 j,但它们仍然是 2 个独立的、不相关的内存片段。

为什么递增指针会把你放在 a[] 的开头,这个神秘的行为可以用 ja[] 这两个事实来解释 分配在堆栈上。 j 的地址可能就在 a[] 的地址下方。事实上,正如您在我的艺术巨著中看到的那样,如果我们从 &j 向上移动 4 个字节,我们将到达 &a[]


根据 Eugene Sh. 编辑 1:

请注意:像这样递增指针是 C 程序中的未定义行为。堆栈上变量的顺序是未定义的,取决于编译器,每次重新编译代码时可能会得到不同的结果。请永远不要在真正的程序中这样做。执行 p++ 将导致未定义的行为。

编辑 2:

您可以通过打印出所有变量的地址来进行一个很酷的实验。

int main()
{
int a[4] = {5, 2, 6, 4};
int j = a[0];
int* p;

//in printf, %p stands for "print pointer"
printf("&a[0] = %p\n", &a[0]);
printf("&j = %p\n", &j);
printf("&p = %p\n", &p); //the address of a pointer.... craaazy
printf("p = %p\n", p); //should print same address as &j

//..............................
}

关于c - 指针运算;最初必须做两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30740859/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com