《c/c++之结构体,联合体,枚举类型》

本文详细介绍了 C/C++ 中的结构体、联合体及枚举类型的基本概念、定义方式、初始化方法及其成员访问等内容,并提供了实例说明。

《c/c++之结构体,联合体,枚举类型》
本章重点:上述符合数据类型的定义,初始化,成员的访问
【struct】结构体
      类型定义:由一系列具有相同数据类型和不同数据类型的数据组成的数据集合。
      类型定义格式:struct worker {char name[10];int age;float salary; struct worker *next;};
      类型变量定义:直接定义struct worker  {char name[10],int age;float salary} hanmeimei;间接定义struct worker {char name[10],int age,float salary};       worker hanmeimei;匿名结构体类型只能直接定义。
     【warning】:结构体分配其成员变量的内存之和。其中每个成员按照被说明的顺序分配存储空间。在c++中变量定义时struct关键字可以省了,但是c语言不能省.结                  构体可以嵌套定义。
      初始化:struct worker hanmeimei = {"hanmeimei",25,100};
      结构体的指针:struct worker Man;struct worker *workerMan=&Man;结构体类型指针指向结构体的起始位置。
      访问成员:结构体变量名.成员名;结构体变量指针->成员名;(*结构体变量指针).成员名
      结构体数组: struct worker workers[20];workers[0]={"hanmeimei",15,80};workers[0].age;
      结构体指针类型参数:实参是结构体变量本身或者结构体指针变量,形参是相同类型的结构体指针类型变量,返回值可以是基本数据类型也可以是结构体类型。
      warning:结构体指针变量+1后的地址取决于此结构体占用内存大小
      结构体处理链表:[此处不明白的可以查看数据结构c语言描述版]
      使用数组储存数据必须先定义数组长度,不适合数据动态增减,链表则没有这个缺点,可以方便的进行数据的插入语删除。
      一般步骤:[1]定义三个结构体指针struct worker *head,*p1,*p2;[2]用new(结构体名)开辟一个新空间储存新节点,然后使p1,p2指向该节点[3]输入节点数据进行
                判断,若是第一个节点则是head指向该节点,则建立了链表的表头[4]若不是第一个节点,则是p2->next=p1;即指向新建立的节点;p2=p1;p2指向此时最
                后一个节点[5]重复3->4[6]判断是最后一个输入的节点,则delete(p1);p2->next=NULL:
      warning :由于p2->next也是指向结构体类型节点,则p2->next成员本身也应该是该结构体类型指针。产生链表的函数应该返回该链表的表头。
【union】联合体
       类型定义:由几种不同类型的变量存放到同一地址的开始的一段内存空间里。又叫共用体。
       类型定义格式: union 共用体名 {char name[20];int age;float salary};
       类型变量定义: 直接定义,间接定义
      【区别于结构体】:对内存空间的占用方式不同。结构体中每个成员都有独立的空间,结构体的内存空间大小等于成员内存大小之和,共用体中成员共用同一地址开
        始的内存空间,总长度取决于单个成员的最大长度,在某一瞬间只能存放每一个成员的数据。既瞬间只有一个成员有效,其他成员无效。
      【访问成员】
        联合体变量名.成员名;联合体指针变量->成员名;
      【warning】 :在联合体变量中,当新成员被赋值后,原有成员内存中重复的地址段被覆盖,也是冲掉。联合体类型可以和结构体类型相互嵌套定义。
       联合体变量不能作为函数参数:编译时要语法检查确定参数类型,但是联合体变量的地址与其各成员的地址相同吗,不能够确定参数类型。但是指向联合体变量的
       的联合体类型型指针变量可以作为函数采纳数,函数也可以返回联合体类型指针变量。
       作用 :联合体经常用于数据类型转换,这是因为可以用两种或者多种方法访问包含在联合厅内的成员数据。因此在编写软件系统时,要处理不同类型的数据,或者
       要求以不同字节为单位(8位或者16位)参加运算,常常用联合体的方式。
【enum】枚举类型
       定义:一个有名字的整形常量的集合。
       定义格式:enum 枚举名称 {枚举元素1[=1],枚举元素2[=2]};个元素之间用逗号隔开,最后一个元素后边不用逗号。
      【warning】: 每个元素都是一个整数值。定义时若无赋值,编译器安定义顺序赋值为0,1,2,3...若其前边又被赋值的则以其左边的元素的值为基准开始复制;枚
       被视为常量,在枚举类型定义之外,均不能能对其赋值。在定义中各枚举元素不能重名,程序中其他标志符也不能与枚举元素重名。
       访问元素:他不需要.,->运算符,而是在枚举类型定义之外直接访问。枚举元素作为整型常量可以直接赋值给枚举变量;整型常量若经过强制类型转换若合法则可        以赋值给枚举类型变量 (enum 枚举类型名)变量名;同类型的枚举类型变量间,枚举元素间,枚举元素和枚举变量间可以进行算术,关系元素运算。枚举类型变量       的作用域遵循一般变量。枚举类型变量可以作为函数采纳数,但返回值必须是枚举类型。
【typedef】定义类型
       typedef 已有数据类型 新的数据类型名;
       typedef int array[10]; array以后偶表示10个元素的整形数组类型;

### C/C++结构体联合体和枚举体的初始化方法 #### 1. **结构体的初始化** 在 C 和 C++ 中,可以通过多种方式对结构体进行初始化。以下是常见的几种方法: - **直接初始化** 当定义结构体变量时,可以在大括号 `{}` 中提供初始值列表。这些值会依次分配给结构体中的成员。 ```c struct MyStruct { int a; double b; char c; }; // 定义并初始化结构体变量 MyStruct myVar = {10, 3.14, 'x'}; ``` 如果某些字段不需要显式初始化,则可以用逗号分隔符跳过未指定的部分[^5]。 - **嵌套结构体的初始化** 对于包含其他结构体作为成员的情况,可以逐层展开初始化。 ```c struct Address { char city[50]; char street[50]; }; struct Student { char name[50]; int age; struct Address addr; // 嵌套结构体 }; // 初始化嵌套结构体 Student s1 = {"Alice", 20, {"New York", "5th Avenue"}}; printf("City: %s\n", s1.addr.city); ``` - **使用 `typedef` 创建别名后的初始化** 通过 `typedef` 可以为结构体创建一个新的名称以便简化代码书写。此时可以直接利用该新名称完成初始化而无需再写入 `struct` 关键字。 ```c #include <stdio.h> typedef struct test { int age; char name[10]; } Student; int main() { // 利用 typedef 后的新类型名进行初始化 Student student = {18, "小明"}; } ``` #### 2. **联合体 (Union) 的初始化** 联合体允许不同的数据类型共享同一内存区域,在初始化时只需为其第一个成员赋予一个值即可影响整个联合体内存布局。 ```c union Data { int i; float f; char str[20]; }; // 对 union 进行初始化,默认只针对首个成员有效 Data data = {10}; /* 此处仅整型变量'i'被设置成了数值10, 如果想让浮点数或者字符串得到特定初值则需单独赋值 */ data.f = 220.5f; strcpy(data.str,"Hello"); ``` 需要注意的是,尽管我们能够一次性设定多个不同类型的值于同一个联合体内,但实际上每次存储都会覆盖前次的内容因为它们共用了相同的物理地址空间[^2]。 #### 3. **枚举体 (Enum) 的初始化** 虽然严格意义上讲,“初始化”这一概念并不适用于枚举项本身(由于其本质上是一系列常量),但我们仍然能够在程序运行期间动态地将某个具体值关联至某枚举对象之上。 ```c enum Color { RED=1, GREEN, BLUE }; Color colorObj; colorObj = RED; /* 显式的把RED这个预设好的整数值给予我们的自定义颜色实例 */ if(colorObj == RED){ puts("The selected color is Red."); } ``` 在这里可以看到,即使没有传统意义上的“构造器”,依然可通过简单赋值语句实现类似效果;而且得益于编译期解析特性,效率极高且安全性良好[^3]。 --- ### 示例代码综合展示 下面给出一段完整的示例代码,演示了如何分别初始化结构体联合体以及枚举体。 ```cpp #include<stdio.h> #include<string.h> // Structure definition and initialization example struct Person{ char firstName[20], lastName[20]; int yearOfBirth; }; Person personInstance={"John","Doe",1990}; // Union definition and initialization example union ValueHolder{ long lValue; short sArray[2]; }; union ValueHolder holder={123L}; // Initialize with first member of the union. // Enum definition and usage example enum Days{SUN, MON, TUE, WED, THU, FRI, SAT}; enum Days today=SAT; int main(){ printf("Name:%s %s Born In:%d\n",personInstance.firstName,personInstance.lastName,personInstance.yearOfBirth); holder.sArray[0]=holder.lValue>>16; holder.sArray[1]=(short)(holder.lValue&0xFFFF); printf("Long value split into shorts:[%hd,%hd]\n",holder.sArray[0],holder.sArray[1]); switch(today){ case SUN :puts("Today's Day Is Sunday.");break; default :puts("It's another day..."); } return 0;} ``` ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值