堆栈的内存地址

时间:2015-03-11 04:50:20

标签: c pointers

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    struct s1 {
        char *z;
        int i;
        struct s1 *p;
    };
    struct s1 *ptr;
    static struct s1 a[] = {
        {"Nagpur", 1, a + 1},
        {"Raipur", 2, a + 2},
        {"Kanpur", 3, a}
    };
    ptr = a;

    printf("%p\n", a[0]);
    printf("%p\n", a[1]);
    printf("%p\n", a[2]);
    printf("%p\n", ptr);
    printf("%p\n", a[2].p);
    printf("%p\n", a[1].p->p);
    printf("%p\n", a);

    return EXIT_SUCCESS;
}

每当我们有一个数组时,假设我们称之为a[10],那么aa[0]的地址是相等的。但在上述情况下,a的地址与a[0]的地址不同。我无法弄清楚为什么?

5 个答案:

答案 0 :(得分:3)

这里传递给printf()的是结构本身,而不是指向它的指针:

printf("%p\n", a[0]);

此代码的行为定义不明确。 (实际上,它通常会最终打印出结构的第一个元素,但这可能不一致。)你可能想要的是:

printf("%p\n", &a[0]);
               ^

答案 1 :(得分:1)

如果你编译时启用了警告(例如gcc -Wall -Werror),你会看到这一行:

printf("%p\n", a[0]);

无效:

ptr.c:20:5: error: format ‘%p’ expects argument of type ‘void *’, but
argument 2 has type ‘struct s1’ [-Werror=format=]
     printf("%p\n", a[0]);
     ^

您正在使用该结构的第0个元素,换句话说,取消引用a,并将struct s1 按值传递给printf,他正在做你说,把它解释为一个指针。

如果您改为地址数组的第一个元素,您会看到它们确实位于同一地址:

printf("%p\n", &a[0]);

答案 2 :(得分:0)

两者不同的原因是当你打印a,它只是引用,而a [0]用于去引用。尝试printf(&#34;%p \ n&#34;,&amp; a [0])。

答案 3 :(得分:0)

使用a [x]参数调用printf()将不会打印地址,而是打印该偏移量的内容。此线段:'那么a或a [0]的地址相等'不成立。但是,a的地址和[0]的地址相等是正确的。 '%p'格式转换器仅用于地址。所以代码需要使用地址,而不是内容。

建议使用类似的东西:

printf("%p\n", &a[0]); 
printf("%p\n", &a[1]);
printf("%p\n", &a[2]);
printf("%p\n", ptr);
printf("%p\n", a[2].p);
printf("%p\n", a[1].p->p);
printf("%p\n", a);

答案 4 :(得分:0)

您正在分配字符串的地址(例如“nagpur”)字符指针。这些字符串将出现在代码部分中。所以“z”将具有这些字符串的地址,并且您正尝试通过打印[0]来打印这些字符串。你应该打印&amp; a [0]。 a [0]是与*(a + 0)类似的操作。所以,如果你想打印它的地址,你应该使用&amp;操作