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]);
填充数组如何在内存中排列? 填充为数组的名称返回数组的基地址...类似&填充。但 fill [0]给出一些未知值,可能是地址和googly部分是& filled [0] 给出值10.我无法得到逻辑。以下是我得到的输出
[2293552,2293552]
[4206592,10]
[2293560,2293568]
[4206595,20]
答案 0 :(得分:3)
%u
中的格式说明符printf
需要unsigned int
类型的参数。您正在为它提供完全不相关类型的参数:指针和结构类型的对象。因此,您的代码会显示未定义的行为。代码被破坏,其输出完全没有意义。试图分析或解释它并没有多大意义。 (解释当然存在,但它与主要问题无关。)
至于如何在内存中排列数组... StackOverflow充满了对这个问题的重复答案。只需进行搜索。
答案 1 :(得分:2)
您的代码
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有一个限制。底层函数实际上看不到你的参数 - 它只是在堆栈上获取数据,它使用打印格式作为指南。
最终,错误的是你将 struct 作为printf参数传递。
printf("[%u,%u]", filled[0], &filled[0]);
filled[0]
解析为struct abc
。
正在发生的事情是程序将fill [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从不使用“&amp; filled [0]”的值,因为您没有指定正确的格式来读取堆栈上的数据。如果您改为使用
printf("filled[0].str=%p, filled[0].i=%u, &filled[0]=%p\n", filled[0], &filled[0]);
那么你会获得更有意义的数据,但这是一种实现结果的危险方式,因为它对数据布局和堆栈做了很多假设。
从根本上说,问题在于你是这样做的:
printf(“%u”,填充[0]);
其中fill [0]不是简单的数据类型。