有没有办法复制具有相似内容的两种不同结构类型,而无需按变量复制变量?
例如,读取文件,保存到pessoa
并复制到xpessoa
,假设email
为'not defined'
。
struct pessoa {
char nome[50];
char telefone[20];
struct{
int dia,mes,ano;
}data_nasc;
};
struct xpessoa {
char nome[50];
char telefone[20];
struct{
int dia,mes,ano;
}data_nasc;
char email[50];
};
答案 0 :(得分:6)
保证可行的方法是将pessoa
嵌入xpessoa
,如下所示:
struct xpessoa {
pessoa p;
char email[50];
};
如果pessoa
布局发生更改,此方法可以保护您的代码免受未定义的行为影响,因为xpessoa
不再镜像其布局。
答案 1 :(得分:1)
如果由于某种原因你不允许改变任何一种结构,你可以这样做:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct pessoa {
char nome[50];
char telefone[20];
struct{
int dia,mes,ano;
}data_nasc;
};
struct xpessoa {
char nome[50];
char telefone[20];
struct{
int dia,mes,ano;
}data_nasc;
char email[50];
};
int main() {
struct pessoa p = {"John", "111-222", {1, 2, 3}};
struct xpessoa xp = { .email = "john@org.org"};
memcpy(&xp, &p, sizeof(p));
printf("name: %s email: %s \n", xp.nome, xp.email);
return 0;
}
然而,正如@dasblinkenlight所说,这将是一种非常危险的方法,因为它需要手动跟踪这两种结构。
答案 2 :(得分:0)
如果你不能改变“扩展”结构以包含“基础”结构作为其初始成员,将整个“基础”结构复制到“扩展”结构的唯一合法方法是定义包含两个结构的联合作为成员的类型。
引用C11第6.5.2.3节(结构和工会成员)第6段:
为了简化联合的使用,我们做了一个特别的保证:如果一个联合包含几个共享一个共同初始序列的结构(见下文),并且如果联合对象当前包含这些结构中的一个,则允许检查其中任何一个的共同初始部分,可以看到完整类型的联合声明。如果对应的成员具有一个或多个初始成员的序列的兼容类型(并且对于位字段,具有相同的宽度),则两个结构共享公共初始序列。
因此,您可以定义包含struct pessoa
和struct xpessoa
类型成员的联合,并从任一成员访问公共部分:
union upessoa {
struct pessoa p;
struct xpessoa xp;
};
int somefunc(void) {
union upessoa a = { .p = {"Fred", "555-5555", {1, 2, 3} };
// This is legal because data_nasc is part of the common initial sequence
return a.xp.data_nasc.ano;
}
根据我的经验,许多代码忽略了结构成为联合成员的这一要求,并假设如果任何两个结构共享一个共同的初始序列,则可以在不同结构的对象之间复制公共初始序列类型;但这会导致未定义的行为 - 它可能会起作用,但它不可移植。