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]
组成
str
和i
的字节的确切顺序将取决于体系结构。现在,你的代码。。。
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]不是简单的数据类型。