mylogo

退役程序员的茶室 RetiredCoder.cn

← 返回上一页

C++编程基础: 13. 结构体与联合体

2025-04-16 04:22:20

本系列文章是配合我发布的《C++编程基础》系列视频教程的知识点总结和补充。这一节我们来讲讲结构体与联合体。

struct 结构体

在类的概念还没引入C语言时,可以用被称为struct的数据结构来实现将不同类型的数据集合到一起来作为一个整体来处理。

结构体的定义:

struct 结构体名称{
    数据类型 成员名称;    
    数据类型 成员名称;
    ......
};

例如,这里定义一个图书相关的结构体,里面的成员就是书的一些属性,例如书名、价格,另外其中还包含了一个添加这些属性具体值的函数:

struct book{
    std::string name; 
    float price; 
    void addBook(std::string bookname, float bookprice){
        name=bookname; 
        price=bookprice; 
    }
};

结构体的定义可以在main函数之外作用于全局,也可以在main函数之内,但只在这个函数之内有效。在声明一个结构体变量时,可以用赋值语句对其进行赋值,等号右边是包含这些成员具体值的大括号,每个成员之间以逗号分隔。

book bookOne={"Harry Potter", 23.5};
book bookTwo={"The Little Price", 10};

类class中的成员默认情况下是私有的(private)访问权限,而struct的成员默认的访问权限都是公有的(public),因此在定义之后,调用时可以用“结构体名称.成员名称”来直接访问。

std::cout<<"The Book One:"<<bookOne.name<<", $"<<bookOne.price<<std::endl;
std::cout<<"The Book Two:"<<bookTwo.name<<", $"<<bookTwo.price<<std::endl;
book bookThree;bookThree.addBook("Gone", 35.4);
std::cout<<"The Book Three:"<<bookThree.name<<", $"<<bookThree.price<<std::endl;

结构体中的成员可以是某个数据类型,也可以是数组、指针,甚至可以包含另一个结构体,这里我们使用了一个匿名的结构体来将书的出版信息对应的成员包含在一起。

struct book{ 
    std::string name; 
    float price; 
    void addBook(std::string bookname, float bookprice){ 
        name=bookname; 
        price=bookprice; 
    } 
    struct{ 
        std::string publisher; int year; 
    };
};

声明时进行对这些成员进行赋值,可以这样写:

book bookOne={"Harry Potter", 23.5,{"Penguin", 2001}};

调用这些成员的值,可以这样写:

std::cout<<"The Book One:"<<bookOne.name<<", $"<<bookOne.price<<"\nPublisher:"<<bookOne.publisher<<" Publish Date:"<<bookOne.year<<std::endl;

union 联合体/共用体

union的特点是一个联合体里可以有不同数据类型的成员,但这些成员在存储空间里占用同一个位置,也就是说,当给其中一个成员赋值时,也会让这个联合体中其他成员的值发生变化。

联合体的定义:

union 联合体名称{
    数据类型 成员名称;    
    数据类型 成员名称;
    ......
};

例如,以ASCII码为例,计算机里的数据实际都是0或1的组合,像英文字母这样的字符,对应的计算机编码可以用十进制的整数来表示,创建这样一个联合体,可以很简单的查到这些简单字符的对应整数值。

union ascii{ 
    char ch; 
    int number;
};

在程序中的声明、赋值和调用:

ascii charA;
charA.ch='A';
charA.number=63;
std::cout<<"The Letter charA:"<<charA.ch<<" "<<charA.number<<std::endl;

一个联合体在存储空间所占大小,是以成员中数据类型所占空间最大的那个为准,我们可以通过sizeof()函数来观察一个联合体变量的大小:

std::cout<<"The Size:"<<sizeof(charA)<<std::endl;

另外,联合体中也是可以包含方法的:

union ascii{ 
    char ch; 
    int number; 
    double d; 
    void print(){ std::cout<<"ch:"<<ch<<" number:"<<number<<std::endl; 
    }
};

要在程序中调用这个方法,可以这样:

charA.print();

另外,union也可以匿名来定义,例如,可以把一个匿名的union包含在一个struct结构体中:

struct book{ 
    std::string name; 
    float price; 
    void addBook(std::string bookname, float bookprice){
        name=bookname; 
        price=bookprice; 
    } 
    struct{ 
        std::string publisher; 
        int year; 
    }; 
    union{ 
        char type_char; 
        int type_int; 
    };
};

程序里的调用:

book bookOne={"Harry Potter", 23.5,{"Penguin", 2001},'H'};
std::cout<<"The Book One:"<<bookOne.name<<", $"<<bookOne.price<<"\nPublisher:"<<bookOne.publisher<<" Publish Date:"<<bookOne.year<<" Type:"<<bookOne.type_char<<std::endl;

输出结果:

The Book One:Harry Potter, $23.5
Publisher:Penguin Publish Date:2001 Type:H