一、共用体(union)
1. 什么是共用体?
共用体(union)也是一种构造数据类型。
与结构体不同:
结构体中所有成员变量同时存在
共用体中的所有成员变量共享同一块内存空间
也就是说:
共用体一次只能保存一个成员变量的数据。
2. 共用体定义格式
语法:
union 共用体名称 { 数据类型 成员1; 数据类型 成员2; ... };例如:
union Data { int a; float b; char c; };定义了一个共用体类型:
union Data二、共用体变量定义
方法一:先定义类型,再定义变量
union Data { int a; float b; char c; }; union Data data;方法二:定义时创建变量
union Data { int a; float b; char c; }data;三、共用体成员访问
使用:
.访问。
例如:
data.a = 10; printf("%d",data.a);示例:
#include<stdio.h> union Data { int a; float b; }; int main() { union Data data; data.a=10; printf("%d\n",data.a); data.b=3.14; printf("%f\n",data.b); return 0; }输出:
10 3.140000但是:
data.b=3.14;之后:
data.a的数据会被覆盖。
原因:
两个成员共用同一块内存。
四、结构体和共用体区别
| 区别 | struct | union |
|---|---|---|
| 内存 | 每个成员独立空间 | 所有成员共享空间 |
| 数据保存 | 所有成员同时有效 | 只有一个成员有效 |
| 大小 | 所有成员大小之和(考虑对齐) | 最大成员大小 |
| 用途 | 保存多个相关数据 | 节省内存 |
例如:
结构体:
struct Test { int a; char b; };内存:
a空间 + b空间共用体:
union Test { int a; char b; };内存:
a | b共享同一块空间。
五、枚举(enum)
1. 什么是枚举?
枚举是一种构造数据类型。
用于表示:
一组固定的取值。
例如:
星期:
星期一 星期二 星期三 ...性别:
男 女状态:
运行 停止 暂停六、枚举定义格式
enum 枚举名称 { 枚举值1, 枚举值2, ... };例如:
enum Week { MONDAY, TUESDAY, WEDNESDAY };默认情况下:
第一个枚举值为:
0例如:
MONDAY = 0 TUESDAY = 1 WEDNESDAY = 2七、枚举变量使用
定义:
enum Week day;赋值:
day=MONDAY;示例:
#include<stdio.h> enum Week { MONDAY, TUESDAY, WEDNESDAY }; int main() { enum Week day; day=MONDAY; printf("%d\n",day); return 0; }输出:
0八、枚举的优点
相比直接使用数字:
int status=1;无法知道:
1代表什么?使用枚举:
enum Status { RUN, STOP };代码可读性更高。
九、位运算
1. 什么是位运算?
计算机中所有数据最终都是二进制形式存储。
例如:
十进制:
5二进制:
0101位运算就是:
对数据的二进制位进行操作。
十、位运算符
C语言提供:
| 符号 | 名称 |
|---|---|
| & | 按位与 |
| | | 按位或 |
| ^ | 按位异或 |
| ~ | 按位取反 |
| << | 左移 |
| >> | 右移 |
十一、按位与(&)
规则:
1 & 1 = 1 其他 = 0例如:
5: 0101 3: 0011 & ---- 0001结果:
1代码:
int a=5; int b=3; printf("%d",a&b);十二、按位或(|)
规则:
只要有一个1,结果就是1例如:
0101 0011 | 0111结果:
7十三、按位异或(^)
规则:
相同为0 不同为1例如:
0101 0011 ^ 0110结果:
6十四、左移和右移
左移
<<例如:
5<<1二进制:
0101左移:
1010结果:
10右移
>>例如:
8>>1二进制:
1000右移:
0100结果:
4十五、位运算应用
1. 判断奇偶
整数最低位:
0 偶数 1 奇数代码:
if(num & 1) { printf("奇数"); } else { printf("偶数"); }2. 设置某一位
例如:
a |= (1<<3);将第3位置1。
3. 清除某一位
a &= ~(1<<3);将第3位置0。
十六、内存管理
1. 为什么需要动态内存?
之前定义变量:
int a;属于:
栈空间
特点:
自动分配
自动释放
但是:
有些情况下不知道需要多少空间。
例如:
用户输入学生数量:
请输入学生人数: 100需要动态创建100个学生空间。
这时候需要:
动态内存分配
十七、动态内存函数
C语言提供:
头文件:
#include <stdlib.h>常用函数:
| 函数 | 作用 |
|---|---|
| malloc | 申请空间 |
| calloc | 申请并初始化 |
| realloc | 重新调整空间 |
| free | 释放空间 |
十八、malloc函数
格式:
malloc(空间大小);例如:
申请10个int:
int *p; p=(int*)malloc(10*sizeof(int));申请成功:
返回:
空间首地址失败:
返回:
NULL完整代码:
#include<stdio.h> #include<stdlib.h> int main() { int *p; p=(int*)malloc(10*sizeof(int)); if(p==NULL) { printf("申请失败"); return -1; } p[0]=100; printf("%d\n",p[0]); free(p); return 0; }十九、free释放内存
动态申请的空间:
不会自动释放。
必须:
free(p);否则会产生:
内存泄漏
二十、calloc函数
区别:
malloc:
申请空间,不初始化。
calloc:
申请空间,并初始化为0。
格式:
calloc(数量,大小);例如:
int *p; p=(int*)calloc(10,sizeof(int));二十一、realloc调整空间
用于改变已经申请的空间大小。
例如:
p=realloc(p,20*sizeof(int));原来:
10个int调整:
20个int二十二、动态数组示例
#include<stdio.h> #include<stdlib.h> int main() { int n; scanf("%d",&n); int *arr; arr=(int*)malloc(n*sizeof(int)); for(int i=0;i<n;i++) { arr[i]=i; } for(int i=0;i<n;i++) { printf("%d ",arr[i]); } free(arr); return 0; }总结
本节学习了 C 语言中的高级数据类型和内存管理:
共用体 union
特点:
多个成员共享内存
节省空间
枚举 enum
特点:
表示固定状态
提高代码可读性
位运算
掌握:
& | ^ ~ << >>应用:
标志位控制
权限管理
底层开发
动态内存管理
重点:
malloc() calloc() realloc() free()