【问题标题】:Purpose of declaring an struct variable inside union在 union 中声明结构变量的目的
【发布时间】:2019-11-21 00:52:01
【问题描述】:

我有这样的代码

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;
}

输出: enter image description here

【问题讨论】:

  • 为什么你认为它与任何其他工会不同?
  • 联合是一组共享相同起始内存地址的变量,并且是最大的成员。如果其中一个成员是结构,那么它将至少与结构一样大(因此它将能够包含一个)。如果另一个成员(如这里)是一个字节数组,那么您也可以将联合的内容作为字节数组读取或写入。
  • 你了解工会的一般用途吗?
  • 是的,sir union 允许在同一个内存位置存储不同的数据类型。
  • 它只是用于将结构作为字符数组访问

标签: c struct union


【解决方案1】:

struct 表示笛卡尔积对应的所有字段类型的值。这些值是字段值的有序连接,所有值都存在于每个结构值中。从这个意义上说,您会将字段中的所有值视为值的元组或序列,它们代表字段的每种类型。

相反,union 表示内部每个字段的替代,因此该类型的整个值集是其中每个类型的普通联合。

因此,组合(unionstruct)确保您可以设置有序的值序列(struct)或将结构字段视为联合的单一替代方案。简单,对! :)(您也可以将union 作为struct 的字段,这意味着这一次序列中的字段是可能的值集的替代。

让我们看一个例子。假设您有一个应该存储 Real 或 Complex 值的变量。对于 Real,您只需使用一个普通的 float 值(我将故意对此进行复杂化,以查看它如何扩展),对于 Complex,我们将使用它两个 double 值(此选择与其他选择无关以及floatdouble 的精度损失)您可以使用:

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_partmy_variable.complex_number.imaginary_part 作为双精度double 复数的实部和虚部。

请注意,这不是将值从实数转换为复数或反之亦然的方法。事实上,在这个例子中,两种类型的值在内部都有不同的表示,如果你在变量上存储一个单精度 float 实数并尝试将它作为一个复数访问,你会破坏你的数据(你会有外部管理存储在变量中的值类型,以便了解如何访问它)可存储在变量中的值集将是整组float 实数值,加上(或还有)整套double 对或符合复数的实部和虚部。这就是 union 保留字的来源。

重要的是要考虑一个类型表示可存储在该类型变量中的一组值。这样,struct 允许您存储字段表示的每种类型的值,并且您可以将所有这些类型同时存储在变量上,而 @987654344 @ 仅允许您决定将使用哪种类型(和哪个字段)来存储任何这些字段替代项中的单个值,并且不超过一个。

【讨论】:

    【解决方案2】:

    在 K&R 的书第二版中描述的 C 编程语言中,结构或联合是字节序列,结构或联合成员是将结构或联合中的某些存储解释为该类型的一种方式.在一个结构中,所有成员都分配到不相交的存储区域,而所有联合成员使用相同的存储。

    如果结构的成员是连续存储的,那么给出:

    struct s1 {char a[3],b[5]; };
    struct s2 {char a[5],b[3]; };
    union { struct s1 v1; struct s2 v2; } u;
    

    分配给u.v1.b[3] 的存储也将分配给u.v2.b[1],因此写入其中任何一个都会有效地设置两者的值。

    C 标准允许 C 的其他方言对何时可以读取或写入对象施加额外的限制,无论是在允许实现生成更高效的代码或以其他方式使客户受益的情况下,或者在它的情况下会伤害实施的客户,但实施者不在乎。从来没有任何关于应该预期哪些额外限制的共识,并且因为 C 标准的作者假设实施者将寻求使他们的客户受益,所以从来没有任何真正的努力来制定不依赖于这种仁慈的规则。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-19
      • 2021-12-17
      • 2016-05-09
      • 1970-01-01
      • 2010-11-01
      • 2017-09-20
      • 1970-01-01
      • 2014-04-25
      相关资源
      最近更新 更多