MST

星途 面试题库

面试题:C++联合体中成员变量的内存分配特点

请简述C++联合体中成员变量是如何进行内存分配的,并举例说明在不同成员赋值时,联合体内存的变化情况。
15.9万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. 联合体成员变量内存分配简述
    • 在C++中,联合体(union)是一种特殊的数据类型,它允许不同的数据类型共享同一块内存空间。联合体的大小是其最大成员变量的大小。这意味着联合体为所有成员变量分配的内存空间是基于最大成员变量的需求,所有成员变量都从同一起始地址开始存储。
  2. 举例说明内存变化情况
#include <iostream>

union Data {
    int i;
    float f;
    char c[4];
};

int main() {
    Data d;
    std::cout << "Size of Data union: " << sizeof(d) << std::endl; // 输出联合体大小,在32位系统下,int和float通常为4字节,这里联合体大小为4字节

    d.i = 10;
    std::cout << "After setting d.i = 10: " << std::endl;
    std::cout << "d.i: " << d.i << std::endl;
    std::cout << "d.f: " << d.f << std::endl; // d.f的值是未定义的,因为写入i后,按float解读是无意义的
    for (int j = 0; j < 4; ++j) {
        std::cout << "d.c[" << j << "]: " << static_cast<int>(d.c[j]) << std::endl;
    }

    d.f = 3.14f;
    std::cout << "After setting d.f = 3.14f: " << std::endl;
    std::cout << "d.i: " << d.i << std::endl; // d.i的值是未定义的,因为写入f后,按int解读是无意义的
    std::cout << "d.f: " << d.f << std::endl;
    for (int j = 0; j < 4; ++j) {
        std::cout << "d.c[" << j << "]: " << static_cast<int>(d.c[j]) << std::endl;
    }

    d.c[0] = 'a';
    d.c[1] = 'b';
    d.c[2] = 'c';
    d.c[3] = '\0';
    std::cout << "After setting d.c = \"abc\": " << std::endl;
    std::cout << "d.i: " << d.i << std::endl; // d.i的值是未定义的,因为写入c后,按int解读是无意义的
    std::cout << "d.f: " << d.f << std::endl; // d.f的值是未定义的,因为写入c后,按float解读是无意义的
    std::cout << "d.c: " << d.c << std::endl;

    return 0;
}

在上述代码中:

  • 首先定义了一个联合体Data,它有三个成员:int类型的ifloat类型的f,以及char数组c[4]。由于intfloat在32位系统下通常为4字节,char数组c也是4字节,所以联合体Data的大小为4字节。
  • 当给d.i赋值为10时,这4字节内存存储了整数10的二进制表示。此时如果读取d.f,其值是未定义的,因为按float的格式解读这4字节数据是无意义的。
  • 当给d.f赋值为3.14f时,这4字节内存存储了float类型3.14f的二进制表示。此时如果读取d.i,其值是未定义的,因为按int的格式解读这4字节数据是无意义的。
  • 当给d.c赋值为"abc"时,这4字节内存存储了字符abc\0的ASCII码。此时如果读取d.id.f,其值都是未定义的,因为按intfloat的格式解读这4字节数据是无意义的。