结构体
结构是一种比数组更灵活的数据格式,一个结构可以存储多种类型的数据
1 2 3 4 5 6
| struct inflatable { char name[20]; float volume; double price; };
|
定义之后就可以使用结构体声明变量,与C不同的是,C++允许在声 明结构变量时省略关键字struct
1 2
| inflatable hat; struct inflatable mainframe;
|
与数组一样,C++11也支持将列表初始化用于结构,且等号 =
是可选的
1 2 3 4 5 6 7 8 9 10 11
| inflatable guest = { "Glorious Gloria", 1.88, 29.99 }; inflatable local = {"Audacious Arthur", 3.12}; inflatable other{};
cout << other.name << endl; cout << local.price << endl;
|
运行结果
所以
=
是可选的
- 如果为设置值的情况下,默认为0值
同理在复制过程中,结构体也是值复制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| inflatable guest = { "Glorious Gloria", 1.88, 29.99 };
inflatable other{}; other = guest;
strcpy_s(other.name, sizeof(other.name) - 1, guest.name); other.price = 1.2;
cout << other.price<< endl; cout << guest.price<< endl;
|
运行结果
- 结构体的复制也是值复制,修改并不会影响另外一个结构体对象
- 为什么使用
strcpy_s
而不是使用 strncpy
或者 strcpy
,可以参考 https://www.yuankang.top/2023/07/28/C++/CPP-04-string类/ 中的说明
结构体变量还有其他创建方式
-
声明两个结构体变量
1 2 3 4 5 6
| struct inflatable { char name[20]; float volume; double price; } infla1, infla2;
|
-
直接初始化结构体变量
1 2 3 4 5 6 7 8 9
| struct perks { int key_number; char car[12]; } per = { 7, "Packard" };
|
-
声明结构体变量(无法重复声明一样结构体变量,不建议使用)
1 2 3 4 5
| struct // no tag { int x; int y; } position;
|
共用体
共用体(union)是一种数据格式,它能够存储不同的数据类型, 但只能同时存储其中的一种类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| union one4all { int int_val; long long_val; double double_val; };
one4all pail = {}; pail.bool_val = true; cout << pail.bool_val << endl; cout << pail.int_val << endl; cout << pail.double_val << endl; pail.double_val = 1.1; cout << pail.bool_val << endl; cout << pail.int_val << endl; cout << pail.double_val << endl;
|
运行结果
1 2 3 4 5 6
| 1 1 4.94066e-324 0 -1717986918 1.1
|
从运行结果可以看出
- 未设置共用体情况下,共用体的字段值是未知的
- 当设置一个字段的情况下,另外一个字段将失效
由于共用体每次只能存储一个值,因此它必须 有足够的空间来存储最大的成员,所以,共用体的长度为其最大成员的 长度
将结构体与共用体结合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| struct widget { char brand[20]; int type; union id { long id_num; char id_char[20]; } id_val; };
widget prize; if(prize.type == 1) cin >> prize.id_val.id_num; else cin >> prize.id_val.id_char;
|
可以通过匿名共用体的方式减少名称调用,其成员将成为相同地址处的变量。每次只有一个成员是当前的成员
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| struct widget { char brand[20]; int type; union { long id_num; char id_char[20]; }; };
widget prize; if(prize.type == 1) cin >> prize.id_num; else cin >> prize.id_char;
|
共用体常用于(但并非只能用于)节省内存
枚举
C++的enum提供了另一种创建符号常量的方式,这种方式可以代替const,使用 enum的句法与使用结构相似
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| enum spectrum { red, orange, yellow, greed, blue };
spectrum band; band = yellow; cout << band << endl;
band = spectrum(1); cout << band << " "<< (band == orange) << endl;
|
输出结果
- enum 可以直接通过枚举序号获取
band = spectrum(1);
- 枚举类型可以比较默认从 0 开始
更进一步,可以为枚举设置值
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| enum spectrum { red = 9, orange = 10, yellow = 100, greed = 4, blue = 5 };
spectrum band; band = red; cout << band << endl; band = spectrum(99); cout << band << " "<< (band == orange) << endl;
|
输出结果
- 可以直接使用
spectrum(99)
声明一个新的枚举类型值
- 枚举类型设置的值并没有顺序要求
- 枚举值的最大值 = 枚举量的最大值。找到大于这个最大值的、最小的2的幂,将它减去1,得到的便是取 值范围的上限。
既能顺便设置值,又能不设置值,name
1 2 3 4 5 6 7 8 9 10 11
| enum spectrum { red, orange = 0, yellow = 1, greed = 1, blue };
cout << (red == orange) << (orange == yellow) << endl; cout << red << orange << yellow << greed << blue << endl;
|
输出结果
- 默认是从 0 开始的
- 枚举可以设置成相同的值
参考链接
- 《C++ Primer Plus》