C 结构阵列存储器排列

C 结构阵列存储器排列,c,C,填充的数组在内存中是如何排列的? filled是数组的名称,返回数组的基址…类似地&filled。但是 filled[0]给出了一些未知值,可能是地址,而googly部分为&filled[0],其中 给出值10。我搞不懂逻辑。下面是我得到的输出 struct abc filled[]={{"aa",10},{"bb",20}}; printf("[%u,%u]\n",filled,&filled); printf("[%u,%u]\n",filled[0],&

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

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]);

printf
中的格式说明符
%u
需要类型为
unsigned int
的参数。您为它提供了完全不相关类型的参数:结构类型的指针和对象。因此,代码表现出未定义的行为。代码被破坏,其输出完全没有意义。试图分析或解释它没有多大意义。(解释当然存在,但与主要问题无关。)


至于数组在内存中的排列方式。。。StackOverflow充满了对这个问题的重复回答。只需进行搜索。

格式说明符
%u
printf
中需要类型为
unsigned int
的参数。您为它提供了完全不相关类型的参数:结构类型的指针和对象。因此,代码表现出未定义的行为。代码被破坏,其输出完全没有意义。试图分析或解释它没有多大意义。(解释当然存在,但与主要问题无关。)

至于数组在内存中的排列方式。。。StackOverflow充满了对这个问题的重复回答。只需进行搜索。

您的代码

[2293552,2293552]    
[4206592,10]    
[2293560,2293568]    
[4206595,20]    
在进一步讨论这个问题之前,我们需要了解一下“struct”是什么样子的。你没有给出定义,所以我假设它是

struct abc filled[]={{"aa",10},{"bb",20}};    
printf("[%u,%u]\n",filled,&filled);
printf("[%u,%u]\n",filled[0],&filled[0]);
因此,
filled
是这些对象的数组:

struct abc {
    const char* str;
    int i;
};
filled[0]
引用空间中的第一个结构abc

filled[] = {
    struct abc { str = "aa", i = 10 },
    struct abc { str = "bb", i = 20 }
};
在内存中,在32位构建中,这些将被布局,其中[…]表示一个字节:

{ str = "aa", i = 10 }
在64位系统上,它们的布局如下

[ptr][ptr][ptr][ptr][i][i][i][i]
构成
str
i
的字节的确切顺序将取决于体系结构

现在,你的代码

[ptr][ptr][ptr][ptr][ptr][ptr][ptr][ptr][i][i][i][i]
printf有一个限制。底层函数实际上看不到您的参数-它只获取堆栈上的数据,并使用打印格式作为指导

最终出现的可怕错误是,您将结构作为printf参数传递

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

发生的情况是,程序将filled[0]的值放入堆栈以供printf使用。格式掩码中的第一个%u使用
str
组件,第二个使用
i

如果这是您的完整计划:

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

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]);
生成的堆栈如下所示

printf从不使用“&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(“%u”,填入[0])

其中填充的[0]不是简单的数据类型。

您的代码

[2293552,2293552]    
[4206592,10]    
[2293560,2293568]    
[4206595,20]    
在进一步讨论这个问题之前,我们需要了解一下“struct”是什么样子的。你没有给出定义,所以我假设它是

struct abc filled[]={{"aa",10},{"bb",20}};    
printf("[%u,%u]\n",filled,&filled);
printf("[%u,%u]\n",filled[0],&filled[0]);
因此,
filled
是这些对象的数组:

struct abc {
    const char* str;
    int i;
};
filled[0]
引用空间中的第一个结构abc

filled[] = {
    struct abc { str = "aa", i = 10 },
    struct abc { str = "bb", i = 20 }
};
在内存中,在32位构建中,这些将被布局,其中[…]表示一个字节:

{ str = "aa", i = 10 }
在64位系统上,它们的布局如下

[ptr][ptr][ptr][ptr][i][i][i][i]
构成
str
i
的字节的确切顺序将取决于体系结构

现在,你的代码

[ptr][ptr][ptr][ptr][ptr][ptr][ptr][ptr][i][i][i][i]
printf有一个限制。底层函数实际上看不到您的参数-它只获取堆栈上的数据,并使用打印格式作为指导

最终出现的可怕错误是,您将结构作为printf参数传递

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

发生的情况是,程序将filled[0]的值放入堆栈以供printf使用。格式掩码中的第一个%u使用
str
组件,第二个使用
i

如果这是您的完整计划:

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

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]);
生成的堆栈如下所示

printf从不使用“&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(“%u”,填入[0])


其中filled[0]不是简单的数据类型。

你能解释一下&filled[0]给出10..的原因吗?@Rakesh_Kumar没有任何解释。AndreyT已经提到,您的代码表现出未定义的行为。实际上,有一个非常简单的解释——他正在按值传递一个结构,10来自他的结构。@Rakesh_Kumar:“原因”这是由于前面的参数
printf
出现问题而导致
printf
参数堆栈区域完全错位。(如果您试图打印
&filled[0]
作为第一个参数,输出将不同。)换句话说,正如我前面所说,您的程序打印的垃圾相当随机,无法以任何与主要问题相关的方式进行解释。您能解释一下&filled[0]给出10..的行为吗?@Rakesh_Kumar没有解释