C 通过强制转换到结构来指定数组

C 通过强制转换到结构来指定数组,c,C,为什么下面的代码可以工作 #include <stdio.h> #define LEN 12 typedef struct { char buffer[LEN]; } string; int main() { char buffer1[LEN] = "Hello World"; char buffer2[LEN]; *(string*)buffer2 = *(string*)buffer1; printf("%s",buffer2);

为什么下面的代码可以工作

#include <stdio.h>
#define LEN 12

typedef struct
{
    char buffer[LEN];
} string;

int main()
{
    char buffer1[LEN] = "Hello World";
    char buffer2[LEN];

    *(string*)buffer2 = *(string*)buffer1;

    printf("%s",buffer2);
    return 0;
}
#包括
#定义LEN 12
类型定义结构
{
字符缓冲区[LEN];
}弦;
int main()
{
char buffer1[LEN]=“你好,世界”;
字符缓冲区2[LEN];
*(字符串*)缓冲区2=*(字符串*)缓冲区1;
printf(“%s”,缓冲区2);
返回0;
}

据我所知,我无法将一个数组分配给另一个。

正如注释中指出的,您不是将数组分配给另一个数组,而是通过强制转换将结构分配给另一个数组。
分配结构会导致复制所有元素(对于简单结构,请参见此)。但是,代码非常糟糕,只需向结构中添加另一个字段,即可将其破坏。

正如注释中所指出的,您并没有将数组分配给另一个数组,而是通过强制转换将结构分配给另一个数组。 分配结构会导致复制所有元素(对于简单结构,请参见此)。但是,代码非常糟糕,只需向结构中添加另一个字段即可将其破坏。

根据您的评论“据我所知,我无法将一个数组分配给另一个数组”。您创建结构似乎是为了避免无法将一个字符串复制到另一个字符串,方法是将缓冲区强制转换到分配中的结构

这一次正好奏效,但并不总是奏效;结构通常在字段之间有填充和对齐位

如果要在C中将一个字符串复制到另一个字符串,请使用
strcpy
strncpy
函数(或者,在
wchar\t
类型字符串的情况下,
wcscpy
wcsncpy

如果要将任意类型的一个数组复制到另一个数组,请使用
for
循环逐个复制每个索引,或使用
memcpy
函数。

根据您的注释“据我所知,我无法将一个数组分配给另一个数组。”创建结构似乎是为了避免无法将一个字符串复制到另一个字符串,方法是将缓冲区强制转换到赋值中的结构

这一次正好奏效,但并不总是奏效;结构通常在字段之间有填充和对齐位

如果要在C中将一个字符串复制到另一个字符串,请使用
strcpy
strncpy
函数(或者,在
wchar\t
类型字符串的情况下,
wcscpy
wcsncpy


如果要将任意类型的一个数组复制到另一个数组,请使用
for
循环逐个复制每个索引,或者使用
memcpy
函数。

C允许将一个结构分配给同一类型的另一个结构,并且这样做的语义是根据结构表示定义的,而不是一个成员一个成员的副本。结构表示包含数组表示并不意味着将包含数组的结构的值分配给另一个结构违反了C禁止将一个数组分配给另一个数组的规定

C还保证结构的第一个成员的地址与结构本身的地址相同,并且它允许在不同的指针类型之间转换对象指针。在这种情况下,这种转换的结果不能保证正确对齐,如果不对齐,则取消引用该结果会产生未定义的行为

另一方面,编译器可以自由地在结构表示中包含尾部填充。通常,这是为了对齐目的而进行的。如果编译器对结构执行此操作(如果对其应用64位或更高的对齐要求,则可能会执行此操作),则赋值将产生未定义的行为。在这种情况下,如果它看起来有效,那是因为你运气好

但是,如果上述未定义行为的来源都不适用,那么期望代码按预期工作确实是合理的。然而,由于很难预测是否会出现这种情况,因此建议您避免使用这样的代码


更好的问题可能是为什么C不允许数组复制。可能有几个原因,但我认为最深层的原因仅仅是为了一致性。在几乎所有的上下文中,当表达式或子表达式计算为数组时,该值衰减为指向第一个数组元素的指针。它包括构成
=
运算符的操作数的子表达式。因此,在普通的C表达式中,数组赋值实际上是指针赋值,并且没有预期的语义。为了允许数组分配,必须仔细地为这种情况设计一个适当的特例。

C允许将一个结构分配给同一类型的另一个结构,这样做的语义是根据结构表示定义的,而不是逐个成员的副本。结构表示包含数组表示并不意味着将包含数组的结构的值分配给另一个结构违反了C禁止将一个数组分配给另一个数组的规定

C还保证结构的第一个成员的地址与结构本身的地址相同,并且它允许在不同的指针类型之间转换对象指针。在这种情况下,这种转换的结果不能保证正确对齐,如果不对齐,则取消引用该结果会产生未定义的行为

另一方面,编译器可以自由地在结构表示中包含尾部填充。通常,这是为了对齐目的而进行的。如果编译器对结构执行此操作(如果对其应用64位或更高的对齐要求,则可能会执行此操作),则赋值将产生未定义的行为。在这种情况下,如果它看起来有效,那是因为你运气好

然而,如果上述两种来源的