struct abc filled[]={{"aa",10},{"bb",20}};
   printf("[%u,%u]\n",filled,&filled);
   printf("[%u,%u]\n",filled[0],&filled[0]);

   printf("[%u,%u]\n",filled+1,&filled+1);
   printf("[%u,%u]\n",filled[1],&filled[1]);

如何在内存中排列填充数组?
filled是数组的名称,返回数组的基地址…类似地&filled。但是
filled[0]给出了一些未知值,可能是地址,而笨拙的部分是&filled[0]
给出值10。我搞不懂逻辑。下面是我得到的输出
[2293552,2293552]
[4206592,10]
[2293560,2293568]
[4206595,20]

最佳答案

你的代码

struct abc filled[]={{"aa",10},{"bb",20}};
printf("[%u,%u]\n",filled,&filled);
printf("[%u,%u]\n",filled[0],&filled[0]);

在我们进一步讨论之前,我们需要了解一下“struct”是什么样子的。你没有给出一个定义,所以我假设它是
struct abc {
    const char* str;
    int i;
};

因此filled是这些对象的数组:
filled[] = {
    struct abc { str = "aa", i = 10 },
    struct abc { str = "bb", i = 20 }
};

filled[0]表示空间中的第一个结构abc。
{ str = "aa", i = 10 }

在内存中,在32位构建中,这些将被布局,[…]表示一个字节:
[ptr][ptr][ptr][ptr][i][i][i][i]

在64位系统上,这些将按
[ptr][ptr][ptr][ptr][ptr][ptr][ptr][ptr][i][i][i][i]

组成stri的字节的确切顺序将取决于体系结构。
现在,你的代码。。。
struct abc filled[]={{"aa",10},{"bb",20}};
printf("[%u,%u]\n",filled,&filled);
printf("[%u,%u]\n",filled[0],&filled[0]);

printf有一个限制。底层函数实际上看不到您的参数-它只是获取堆栈上的数据,并使用打印格式作为指导。
最终,可怕的错误是,您将一个结构作为printf参数传递。
printf("[%u,%u]", filled[0], &filled[0]);

filled[0]解析为astruct abc
正在发生的是程序正在将filled[0]的值放入堆栈中供printf使用。格式掩码中的第一个%u使用str组件,第二个使用i
如果这是您的完整程序:
#include <stdio.h>

struct abc {
    const char* str;
    int i;
};

int main() {
    struct abc filled[] = { { "aa", 16 }, { "bb", 20 } };
    printf("filled = %p\n", filled);
    printf("&filled = %p\n", &filled);
    printf("filled[0] = %p\n", filled[0]);
    printf("&filled[0] = %p\n", &filled[0]);
    printf("filled[0].str = %p\n", filled[0].str);
    printf("filled[0].i = %d\n", filled[0].i);
    return 0;
}

输出如下:
filled = 0xbfba5cb0
&filled = 0xbfba5cb0
filled[0] = 0x80485b0     <--+
&filled[0] = 0xbfba5cb0      | filled[0] actually printed the .str value
filled[0].str = 0x80485b0 <--+
filled[0].i = 16

缺少的是以下编译器警告,因为您正在使用Visual Studio或不使用-Wall进行编译:
prog.c: In function ‘main’:
prog.c:12:5: warning: format ‘%p’ expects argument of type ‘void *’, but argument 2 has type ‘struct abc’ [-Wformat=]
     printf("filled[0] = %p\n", filled[0]);

当你这样做的时候
printf("[%u, %u]\n", filled[0], &filled[0]);

程序执行以下操作:
push stack (const char*) "[%u, %u]\n"   // in 32-bit, 4-bytes of pointer.
push stack (struct abc) filled[0]       // pushes the entire of filled[0], str and i, 8 bytes.
push stack (struct abc*) &filled[0]     // pushes another 4 bytes.

生成的堆栈如下所示
printf从不使用“&filled[0]”的值,因为您没有指定正确的格式来读取堆栈上的数据。如果你用
printf("filled[0].str=%p, filled[0].i=%u, &filled[0]=%p\n", filled[0], &filled[0]);

然后你会得到更有意义的数据,但这是一个危险的方法来实现结果,因为它对数据布局和堆栈做了很多假设。
从根本上说,你的问题在于:
printf(“%u”,填充[0]);
其中填充的[0]不是简单的数据类型。

10-08 14:06