三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

C语言学习笔记(十四)——共用体、枚举、位运算与内存管理

C语言学习笔记(十四)——共用体、枚举、位运算与内存管理

一、共用体(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

的数据会被覆盖。

原因:

两个成员共用同一块内存。


四、结构体和共用体区别

区别structunion
内存每个成员独立空间所有成员共享空间
数据保存所有成员同时有效只有一个成员有效
大小所有成员大小之和(考虑对齐)最大成员大小
用途保存多个相关数据节省内存

例如:

结构体:

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()
← 返回列表