1)结构体
结构体(structure)是一种由不同数据类型的成员组成的数据集合类型,它允许将多个相关的变量组合在一起,形成一个更复杂的数据类型。
1.找成员当中最大的类型 作为对齐
2.按照定义的顺序实现空间分配
3.实现地址分配要整数倍对齐
4.当结构体当中成员为数组时 需要将数组拆分成多个该类型的变量
5. 当结构体当中包含其他结构体类型的结构时 先找到它的对齐数 从而确定结构体的对齐数 再进行分配
位域(不存在地址对齐)
如果相邻成员是同一类型 可以考虑往一个单位内进行分配(如果能装下) 不允许跨单位进行存储
一、结构体的定义
在 C 和 C++中,可以使用关键字struct来定义结构体。例如:
#include<stdio.h>`
`//结构体类型声明`
`struct` `student` `{`
`int age;`
`char name[20];`
`}s;//此时是结构体中变量`
`int` `main()` `{`
`//定义结构体类型的变量`
` s.name[0]='a';`
`printf("%s", s.name);`
`return` `0;`
`}
typedef表示取别名
#include<stdio.h>`
`//结构体类型声明`
`typedef` `struct` `student` `{`
`int age;`
`char name[20];`
`}s;//此时是类型`
`int` `main()` `{`
` s b;`
` b.age;`
`return` `0;`
`}`
`
二、结构体的使用方法
- 定义结构体变量
例如:
` `//可以使用定义好的结构体类型来声明结构体变量`
`struct` `Person person1;`
`//也可以在定义结构体类型的同时声明变量:`
`struct` `{`
`char name[50];`
`int age;`
`float height;`
`} person2;`
`
- 访问结构体成员
通过点运算符(`.`)来访问结构体变量的成员。
例如:
` `strcpy(person1.name,` `"John");`
` person1.age =` `30;`
` person1.height =` `1.75;`
`
- 作为函数参数传递
结构体变量可以作为函数的参数传递,以实现对结构体数据的操作。
例如:
` `void` `printPerson(struct` `Person p)` `{`
`printf("Name: %s\n", p.name);`
`printf("Age: %d\n", p.age);`
`printf("Height: %.2f\n", p.height);`
`}`
`
调用函数时传递结构体变量:
printPerson(person1);`
`
- 结构体指针
可以定义指向结构体的指针,通过指针来访问结构体成员时使用箭头运算符(`->`)。
例如:
` `struct` `Person` `*ptr =` `&person1;`
`printf("Name: %s\n", ptr->name);`
`printf("Age: %d\n", ptr->age);`
`printf("Height: %.2f\n", ptr->height);`
`
三、结构体的作用和意义
- 数据封装
结构体将不同类型的数据组合在一起,形成一个逻辑单元,方便对相关数据进行管理和操作。例如,在描述一个学生的信息时,可以将学生的姓名、学号、成绩等不同类型的数据封装在一个结构体中。
- 提高代码可读性和可维护性
通过使用结构体,可以使代码更加清晰地表达数据的含义和关系。当看到一个结构体变量的使用时,可以很容易地理解它所代表的复合数据的结构和内容。
- 方便数据传递
当需要将多个相关的数据作为一个整体传递给函数时,使用结构体可以避免传递多个独立的参数,减少函数调用的复杂性。
- 模拟面向对象编程中的类
在 C++中,结构体可以包含成员函数,具有一定的面向对象编程的特性。虽然 C++中的类更常用于面向对象编程,但结构体在一些简单的场景下也可以起到类似的作用。
2)联合体
联合体(union)是一种特殊的数据类型,它允许在同一内存位置存储不同的数据类型。
共用体也称联合 任何时候只能有一个成员带有值
数位: 左高右低
地址: 左低右高
大端存储(小端存储相反):低地址放高位,高地址放低位
电脑默认为小端存储
//存储方式的判断`
`int` `checkSystem(){`
`union System{`
`int a;`
`char c;`
`}u;`
` u.a =` `1;`
`return u.c ==` `1;`
`}`
`int` `main(){`
`printf("%d",checkSystem());`
`return` `0;`
`}`
`
一、联合体的定义
在 C 和 C++中,可以使用关键字`union`来定义联合体。例如:
union Data {`
`int integer;`
`char character;`
`float floatingPoint;`
`};`
`
这里定义了一个名为Data的联合体,它包含了三个成员:一个整数integer、一个字符character和一个浮点数floatingPoint。
二、联合体的使用方法
- 定义联合体变量
可以使用定义好的联合体类型来声明联合体变量。例如:
` `union Data data1;`
`
- 访问联合体成员
由于联合体的所有成员共享同一块内存空间,所以在同一时间只能访问其中的一个成员。例如:
data1.integer =` `10;`
`printf("Integer value: %d\n", data1.integer);`
` data1.character =` `'A';`
`printf("Character value: %c\n", data1.character);`
` data1.floatingPoint =` `3.14;`
`printf("Floating-point value: %f\n", data1.floatingPoint);`
`
需要注意的是,对一个成员的赋值会覆盖其他成员的值。
- 联合体的大小
联合体的大小等于其最大成员变量所占的内存空间。可以使用sizeof运算符来获取联合体的大小。例如:
` `printf("Size of union Data: %zu bytes\n",` `sizeof(union Data));`
`
三、联合体的作用和意义
- 节省内存空间
当在不同的时间只需要使用一种数据类型时,联合体可以节省内存空间。例如,如果有一个程序在不同的情况下需要存储整数、字符或浮点数,但在同一时间只需要使用其中的一种类型,那么可以使用联合体来实现,而不是分别为每种类型分配独立的内存空间。
- 数据类型转换
联合体可以用于在不同的数据类型之间进行转换。通过将数据存储在联合体的一个成员中,然后以另一种数据类型的成员来访问,可以实现某种程度上的数据类型转换。但需要注意的是,这种转换可能会导致数据丢失或不正确的结果,因此需要谨慎使用。
- 特定的编程需求
在一些特定的编程场景中,联合体可以提供一种灵活的数据存储和访问方式。例如,在处理网络数据包或文件格式时,可能需要根据不同的标志位来解析不同的数据类型,联合体可以在这种情况下发挥作用。
3) 结构体和联合体有什么区别?能否在声明过程当中缺省名字?
一、结构体和联合体的区别
- 内存分配方式
结构体(struct):结构体中的各个成员占用不同的内存空间,整体的内存大小是所有成员变量所占内存之和。
例如:
` `struct` `Person` `{`
`int age;`
`char gender;`
`float height;`
`};`
`
假设int占 4 个字节,cha`占 1 个字节,float占 4 个字节,那么struct Person类型的变量所占用的内存空间为 4 + 1 + 4 = 9 个字节(实际情况可能因编译器和系统架构有所不同,并且可能会有内存对齐的情况)。
联合体(union):联合体的所有成员共享同一块内存空间,其大小等于联合体中最大的成员变量所占的内存空间。例如:
` `union Data {`
`int num;`
`char letter;`
`double value;`
`};`
`
假设int占 4 个字节,char占 1 个字节,double占 8 个字节,那么union Data类型的变量所占用的内存空间为 8 个字节(同样可能因编译器和系统架构及内存对齐而有所不同)。
- 成员变量的存储和访问
结构体:可以同时存储和访问所有成员变量的值,各个成员变量的值相互独立,互不影响。
联合体:在同一时间只能存储和访问其中一个成员变量的值,因为所有成员共享同一块内存空间。对一个成员变量的赋值会覆盖其他成员变量的值。
- 用途
结构体:通常用于表示具有不同类型属性的复合数据结构,比如描述一个人的信息、一个图形的属性等。
联合体:主要用于在不同的数据类型之间进行灵活的转换,或者在不同的时刻只需要使用一种数据类型的情况,以节省内存空间。
二、能否在声明过程当中缺省名字
- 结构体
可以在声明过程中缺省名字,这种情况下称为匿名结构体。匿名结构体可以在定义变量时直接使用
例如:
` `struct` `{`
`int x;`
`int y;`
`} point;`
`
使用方法:可以像普通结构体变量一样访问成员变量,如`point.x`和`point.y`。
- 联合体
也可以在声明过程中缺省名字,即匿名联合体。匿名联合体的使用方式与匿名结构体类似
例如:
` `union` `{`
`int integer;`
`char character;`
`} data;`
`
使用方法:可以通过成员变量名访问联合体中的值,如data.integer或data.character。需要注意的是,在同一时间只能使用其中一个成员变量。
4 )结构体可以包含函数吗?在 C 和 C++ 中有何不同?
一、结构体中可以包含函数吗?
- 在 C 语言中
C 语言的结构体中不能直接包含函数。但是可以通过函数指针在结构体中模拟类似包含函数的行为。
例如:
` `struct` `MyStruct` `{`
`int data;`
`void` `(*processData)(struct` `MyStruct*);`
`};`
`void` `processFunction(struct` `MyStruct* s)` `{`
` s->data++;`
`}`
`int` `main()` `{`
`struct` `MyStruct s =` `{5, processFunction};`
` s.processData(&s);`
`printf("%d\n", s.data);`
`return` `0;`
`}`
`
- 在 C++中
C++的结构体可以直接包含函数。在 C++中,结构体和类的区别主要在于默认的访问权限不同(结构体默认是 public,类默认是 private)。
例如:
` `struct` `MyStruct` `{`
`int data;`
`void` `processData()` `{`
` data++;`
`}`
`};`
`int` `main()` `{`
` MyStruct s =` `{5};`
` s.processData();`
` std::cout << s.data << std::endl;`
`return` `0;`
`}`
`
二、C 和 C++中结构体包含函数的不同之处
- 语法支持
C 语言需要通过函数指针来间接实现类似结构体包含函数的效果,语法相对复杂。
C++直接支持在结构体内部定义函数,语法更加简洁直观。
- 访问权限
C 语言中结构体的成员默认是公共访问权限,但没有真正意义上的访问控制关键字来限制成员的访问。
C++结构体的成员默认也是公共访问权限,但可以使用访问控制关键字(如 public、private、protected)来明确地控制成员的访问权限,提供了更好的封装性。
- 面向对象特性
C++中的结构体可以结合函数实现一些面向对象的特性,如封装、继承和多态(通过继承和虚函数实现多态)。虽然 C++的结构体通常不被用于复杂的面向对象设计,但在一些简单的场景下可以方便地模拟类的行为。
C 语言的结构体主要用于数据的组合,不具备面向对象的特性。