C++ | C++ 基础知识 | 结构、联合与枚举

时间:2019-11-27
本文章向大家介绍C++ | C++ 基础知识 | 结构、联合与枚举,主要包括C++ | C++ 基础知识 | 结构、联合与枚举使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

1. 结构

1.0 结构

数组是相同类型元素的集合,相反,struct 是任意类型元素的集合。
代码例子:

struct Address {
    const char* name;
    int number;
    const char* street;
    const char* town; 
}
// 初始化:
Address jd = {"zs", 1, "jd", "t"};
// 赋值
jd.name = "ls";
cout << jd.name << endl;
// 取值
void print_add1(const Address* add)
{
    cout << add->name << endl
    << add->number << endl
    << add->street << endl 
    << add->town << endl
}
// 如果 add 是一个指针,则 p->m 等价于 (*p).m
// 也可以使用 . 运算符访问它
void print_add2(const Address& add)
{
    cout << add.name << endl 
    << add.number << endl 
    << add.street << endl
    << add.town   << endl
}

结构体类型的对象也可以被赋值和作为实参传入函数,或者作为函数的结果返回。

1.1 布局

结构体形式:

struct Readout{
    char hour;
    int value;
    char seq;
}  // sizeof() -> 12

struct Readout{
    int value;
    char hour;
    char seq;
} // sizeof() -> 8

内存在为成员分配空间时,顺序与声明结构的时候保持一致,因此,hour 的地址一定在 value 之前。在计算机中,很多机器要求一些特定类型的对象沿着系统结构设定的边界分配空间,以便机器能高效地处理这些对象。上述代码的结构体大小使用sizeof(Readout)计算时,真正的结果为 12。
实际编写过程中可以按照各自的尺寸排序(大的在前面),这样可以在一定程度上减少空间的浪费。

1.1 名字

类型名字一出现即可马上使用,无需等全部声明完成,但是等到 struct 的声明全部完成,才能声明它的对象。

struct Link {
    Link* previous;  // 正确
    Link* successor; // 正确 
}

struct No_good {
    No_good member;  // 错误,因为此时编译器无法确定 No_good 的大小
}

多个 struct 相互引用,需要提前声明好 struct 的名字

struct List;
struct Link {
    Link* pre;
    Link* suc;
    Link* member_of;
    int data;
}
struct List {
    Link* head;
}

1.2 结构与类

struct 是一种 class, 它的成员默认是 public 的。struct 可以包含成员函数,尤其是构造函数。

struct Point
{
    int x; 
    int y;
};
struct Points   
{
    vector<Point> elem; 
    Points(Point p0) { elem.push_back(p0); }
    Points(Point p0, Point p1) { 
       elem.push_back(p0); 
       elem.push_back(p1); }
};


int main()
{
    Points x1{ {100,200} };
    cout << "Hello Word !" << endl;
}

1.2 结构与数组

同理可以定义数组结构体

struct Point {
    int x, y;
}
struct Array {
    Point elem[3];
}
int main(){
    Array points {{1, 2}, {3, 4}, {5, 6}};
    int y2 = points.elem[2].y
}

标准库中的 array 也是一种 struct,与内置数组相比,更加完善。

2. 联合

union 是一种特殊的 struct,它的所有成员都分配在同一地址空间上。因此,一个union 实际占用的空间大小与其最大的成员一样,在同一时刻 union 只能保存一个成员的值。

使用 union 的目的是让数据更紧密,从而提高程序的性能。然而,大多数程序即使使用了 union 也不会提高太多,同时,使用 union 代码容易出错,union 一般最好不要出现在程序中。

enum Type {str, num};
struct Entry {
    char *name;
    Type t;
    char* s; // 如果 t == str,使用 s
    int i;   // 如果 t == num,使用 i
}

在上述代码中 s 和 i 不可能被同时使用,因此空间浪费掉了。因此可以使用 union 解决上述问题。

union Value {
    char* s;
    int i;
}
struct Entry {
    char* name;
    Type t;
    Value v; // 如果 t == str,使用 v.s,如果 t == num 使用 v.i
}

3. 枚举

枚举类型用于存放用户指定的一组整数值。
枚举类型分两种

  • enum class 他的枚举值名字位于 enum 的局部作用域内,枚举值不会隐式地转换成其他类型。
  • 普通的 enum 它的枚举值名字与枚举类型本身位于同一个作用域中,枚举值隐式地转换成整数。
    建议使用 enum class
    ### 3.1 enum class
    enum class 限定了作用域的强类型枚举。

函数调用:

enum class Traffic_light {red, yellow, green}
Traffic_light tr = Traffic_light::red;

枚举常用一些整数类型标识,每个枚举值是一个整数,标识某个枚举的类型称为它的基础类型。基础类型必须是一种带符号或无符号的整数类型,默认是 int。
可以显式地指定:
enum class Warning: int {green, yellow, orange, red}
如果你认为上述的定义太浪费控件,可以使用 char 代替 int:
enum class Warning: char {green, yellow, orange, red}

enum Traffic_light 
{ tl_red, tl_yellow, tl_green };
enum Warning
{ green, yellow, orange, red };
void f(Traffic_light x)
{
    if (x == red)
    {
        printf("red");
    }
    if (x == Warning::red)
    {
        printf("red");
    }
}

3.2 普通的 enum

“普通的 enum” 是指 c++ 在指出 enum class 之前提供的枚举类型,在很多 C 和 C++ 的代码中都存在普通的 enum。普通的 enum 的枚举值位于 enum 本身所在的作用域中,它们隐式地转换成某些整数类型的值。

enum Traffic_light { red, yellow, green}

原文地址:https://www.cnblogs.com/corc/p/c--c-ji-chu-zhi-shi--jie-gou-lian-he-yu-mei-ju.html