c - 在 union 中声明结构变量的目的
问题描述
我有这样的代码
typedef struct
{
unsigned char arr[15]; //size = 15bytes
unsigned char str_cks; //size = 1byte
}iamstruct; //Total Size = 16bytes
typedef union
{
iamstruct var;
unsigned char union_cks[16];
}iamunion; //Total Size = 16bytes
static iamunion var[2];
int main()
{
printf("The size of struct is %d\n",sizeof(iamstruct)); //Output = 16
printf("The size of union is %d\n",sizeof(iamunion)); //Output = 16
var[1].union_cks[1] = 2;
printf("%d",var[1].union_cks[1] ); // Output =2
return 0;
}
我对联合内部的结构变量声明及其工作方式感到困惑?
这样做的主要目的是什么以及它如何提高可访问性?
请分享你的想法。
提前致谢。
我现在从下面的代码中理解了一些东西。这里分配的内存为 16 字节,全部由联合的单个成员共享。
typedef struct
{
unsigned char str_cks1;
unsigned char str_cks2;
unsigned char str_cks3;
unsigned char str_cks4;
unsigned char str_cks5;
unsigned char str_cks6;
unsigned char str_cks7;
}iamstruct;
typedef union
{
iamstruct var;
unsigned char union_cks[7];
}iamunion;
static iamunion var[7];
int main()
{
int i = 0;
printf("The size of struct is %d\n",sizeof(iamstruct));
for(i=0;i<7;i++)
{
var[i].var.str_cks1 = (i*1);
var[i].var.str_cks2 = (i*2);
var[i].var.str_cks3 = (i*3);
var[i].var.str_cks4 = (i*4);
var[i].var.str_cks5 = (i*5);
var[i].var.str_cks6 = (i*6);
var[i].var.str_cks7 = (i*7);
}
for(i=0;i<7;i++)
{
printf("%d\t",var[i].var.str_cks1);
printf("%d\t",var[i].var.str_cks2);
printf("%d\t",var[i].var.str_cks3);
printf("%d\t",var[i].var.str_cks4);
printf("%d\t",var[i].var.str_cks5);
printf("%d\t",var[i].var.str_cks6);
printf("%d\t",var[i].var.str_cks7);
printf("\n");
}
return 0;
}
输出: 在此处输入图像描述
解决方案
Astruct
表示笛卡尔积对应的所有字段类型的值。这些值是字段值的有序连接,并且都存在于每个 struct value中。从这个意义上说,您会将字段中的所有值视为值的元组或序列,它们代表字段的每种类型。
相反,a union
表示内部每个字段的替代,因此该类型的整个值集是其中每个类型的普通联合。
因此,composition (of union
and struct
) 确保您可以设置有序的值序列 ( struct
) 或将 struct 字段视为联合的单一替代方案。简单,对!:) (您也可以将 aunion
作为 a 的字段struct
,这意味着这次序列中的字段是可能的值集的替代。
让我们用一个例子来看看。假设您有一个应该存储 Real 或 Complex 值的变量。对于 Real,您只需使用一个普通float
值(我将故意对此进行复杂化,以查看它如何扩展),对于 Complex,我们将使用它两个double
值(此选择与其他选择无关,并且会丢失afloat
反对 a double
) 您可以使用:
struct complex {
double real_part, imaginary_part;
};
接着
union {
float real_number;
struct complex complex_number;
} my_variable;
那么您可以my_variable.real_number
作为单精度float
值访问,my_variable.complex_number.real_part
也可以作为复数my_variable.complex_number.imaginary_part
的双精度实部和虚部访问。double
请注意,这不是将值从实数转换为复数或反之亦然的方法。事实上,在这个例子中,两种类型的值在内部都有不同的表示,如果你在变量上存储一个单精度float
实数并尝试将它作为复数访问,你将破坏你的数据(你必须在外部管理为了知道如何访问它而存储在变量中的值的类型)可存储在变量中的值集将是float
实数的整组值,加上(或也)整组double
对或实数符合复数的部分和虚部。这是union
保留字的来源。
重要的是要考虑一个类型表示可存储在该类型变量中的一组值。这样,astruct
允许您存储字段表示的每种类型的值,并且您可以将所有这些类型同时存储在变量上,而 aunion
仅允许您决定哪种类型(以及哪个字段)您将使用仅存储任何这些字段替代项的单个值,并且不超过一个。
推荐阅读
- java - 在 Java 7 上使用 maven 和 spring 1.5.22.RELEASE 的 SOAP 服务中通过工厂方法进行的 Bean 实例化失败
- python - Pyinstaller 出现错误 -“未能执行脚本”
- javascript - 带有 livewire 的 laravel 8 中捆绑产品的工作流程
- mongodb - 您可以将两种类型的用户添加到 jwt 策略身份验证中吗?
- c++ - 为什么在堆数组初始化中调用了两次复制构造函数?
- intellij-idea - 我已经尝试了一切,但制表符不适用于 IntelliJ
- isabelle - 为什么在 Isabelle 中证明一个简单的可计算自然等式时必须使用“numeral_nat”或“numeral.simps”
- typescript - 从枚举推断元组类型?
- datadog - 为不同的环境创建相同的 Datadog 图
- node.js - RangeError BITFIELD_INVALID:无效的位域标志或数字