嵌入式基础学习|C语言篇——结构体(含进阶)二

共用体:

union //联合--共用体

在C语言中,共用体(Union)是一种特殊的数据类型,它允许不同类型的数据共享同一块内存空间,其主要特点和相关概念如下:

定义与语法

共用体使用union关键字来定义,语法形式为:

union 共用体名 {

数据类型1 成员名1;

数据类型2 成员名2;

// 可以有多个不同类型的成员

数据类型n 成员名n;

};

例如:

union Data {

int i;

float f;

char c;

};

内存占用

共用体的大小取决于其最大成员的大小。在上述union Data的例子中,如果int类型占4个字节,float类型也占4个字节,char类型占1个字节,那么union Data占用的内存空间为4个字节,因为它要保证能容纳下最大的成员int或float。

成员访问

共用体可以通过成员名来访问其成员,但在某一时刻只能有一个成员的值是有效的。比如:

union Data data;

data.i = 10;

// 此时data.i的值是有效的,data.f和data.c的值是不确定的

data.f = 3.14;

// 此时data.f的值是有效的,data.i和data.c的值被覆盖

使用场景

• 节省内存:当程序需要处理不同类型的数据,但这些数据不会同时使用时,使用共用体可以节省内存空间。

• 数据解析:在网络通信或文件格式解析中,可能会接收到不同类型的数据,但它们在内存中的存储格式是特定的,这时可以使用共用体来方便地解析数据。

⭐️与结构体的区别

结构体的所有成员都有自己独立的内存空间,整个结构体的大小是所有成员大小之和(考虑内存对齐)。而共用体的所有成员共享同一块内存空间,大小取决于最大成员。

早期的时候,计算机的硬件资源有限,

能不能让多个成员变量 公用同一块空间

//使用方式 类似 结构体 --- 也是构造类型

struct 结构体名

{

成员变量名

};

union 共用体名

{

成员变量名

}; //表示构造了一个共用体类型

//定义变量

//定义指针

//定义数组

//做函数形参

//做函数返回值类型

注意:

1.共用体类型的大小 = 最大的成员的大小

2.共用体初始化,只能写一个值,这个值是给第一个成员变量的值

3.共用体成员的访问方式 和 结构体一样

4.共用体因为公用同一块空间

赋值时,后赋值的会影响前面赋值的结果

5.用途

a.节省空间

校园人员管理系统

struct student

{

char name20;

int sno;

float score;

};

struct teacher

{

char name20;

int tno;

float salary;

};

struct member

{

char name20;

int no;

union

{

float salary;

float score;

}data;

};

struct member s;

printf("score = %f\n",s.data.score);

struct member t;

printf("score = %f\n",s.data.salary);

b.数据转换

192.168.0.59 //ip地址 --- 网络环境中 ---实际对应是一个32位的数值

#include <stdio.h>

union Ip

{

unsigned char ip4;

unsigned int iip;

};

int main(int argc, const char *argv\[\])

{

union Ip d = {192,168,0,59};

printf("ip = %#x\n",d.iip);

return 0;

}


枚举:

在C语言中,枚举(Enumeration)是一种用户自定义的数据类型,用于将一组相关的常量用符号名称来表示,方便程序的编写和维护。以下是关于枚举的主要概念:

定义与语法

枚举使用enum关键字来定义,基本语法形式为:

enum 枚举名 {

枚举常量1,

枚举常量2,

// 可以有多个枚举常量

枚举常量n

};

例如,定义一个表示星期的枚举类型:

enum Weekday {

MONDAY,

TUESDAY,

WEDNESDAY,

THURSDAY,

FRIDAY,

SATURDAY,

SUNDAY

};

枚举常量的值

默认情况下,枚举常量会自动被赋予从0开始的整数值,如上述MONDAY的值为0,TUESDAY的值为1,以此类推。也可以手动指定枚举常量的值,例如:

enum Weekday {

MONDAY = 1,

TUESDAY = 2,

// 其他常量按顺序依次递增

SUNDAY = 7

};

枚举变量的定义和使用

可以像使用其他基本数据类型一样定义枚举变量,例如:

enum Weekday today;

today = MONDAY;

然后可以在程序中根据枚举变量的值进行相应的操作,比如:

if (today == MONDAY) {

// 执行周一的相关操作

}

使用场景

• 提高代码可读性:用有意义的枚举常量名代替数字常量,使代码更易理解,如用MONDAY代替0来表示星期一。

• 限定取值范围:在函数参数或变量定义中使用枚举类型,可以限定其取值只能是枚举中定义的常量,有助于进行数据检查和错误处理。

• 状态标识:用于表示程序中的各种状态,如表示文件操作的状态,可以定义一个枚举来表示打开成功、打开失败、读取成功等状态。

练习:

学会从键盘输入 1到7 打印对应的星期 (英文)

如果一个变量只有几种可能的值,则可以定义为枚举类型。

所谓"枚举"是指将变量的值一一列举出来,变量的值只限于列举出来的值的范围内。

枚举 --- 提高代码可读性

魔数

幻数

枚举 --- 将变量的可能值(常量值) 一一列举出来

将有关联的常量值,一一列举出来,组合成一个枚举类型

enum 枚举名

{

枚举值

//sun,mon,tue,wed,thu,fri,sat

};

//构造了一个枚举类型

注意:

1.枚举类型 本质是 用int型数据表示的

枚举类型 设计的不严谨的地方

练习:

歌曲的状态

PLAYING 1

PAUSE 2

STOP 3


typedef //type define

表示给已有类型起别名

struct stu

{

};

struct stu s;

union demo

{

};

union demo d;

typedef struct stu s; //s是struct stu 这个类型的别名

s s1; //定义了一个 struct stu的变量

typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler);

void (*signal(int signum, void (*handler)(int) ))(int) ;

typedef int array_t4; //一维数组

array_t b3; //array_t => int4

位运算:

指的是二进制位上的运算

用途:

嵌入式 --- 位运算 非常普遍

操作硬件

c语言位运算:

& 与

| 或

^ 异或

~ 取反

<< 左移

>> 右移

& 与

运算规则: 一假则假

| 或

运算规则: 一真则真

^ 异或

运算规则: 相同为0 不同为1

<< 左移 a<<n

运算规则: 将 左操作数a 左移 n位

左移一位 相当于 结果乘以2

int a = 0x55;

a & 0x33

0101 0101 //0x55

&0011 0011 //0x33


0001 0001 //0x11

0101 0101 //0x55

| 0011 0011 //0x33


0111 0111 //0x77

0101 0101 //0x55

^ 0011 0011 //0x33


0110 0110 //0x66

~ 0101 0101 //0x55

1010 1010 //0Xaa

嵌入式:

unsigned char reg = 0xff;

7654|3210

与 清0

或 置1

7654|3210

1111 1111

& 0


reg & 0xfe

int a;

将a中的所有偶数位 清0

int a = 0x1;

7654|3210

0000 0001 //1

0000 0010 //2

0000 0100 //4

0000 1000 //8

将a中的第5位 清0

~(1<<5)

0010 0000

1101 1111 & a

~(1<<5|1<<8|1<<11)

练习:

int a = 0xffffffff;

将a中的所有偶数位 清0

练习:

int a = 0;

将a中的所有奇数位 置1

1010

7654|3210

0000 0001 //1

0000 0010 //2

0000 0100 //4

0000 1000 //8

1000 0000

1100 0000 0

右移:

要看 要移动的数据的类型

看是有符号 --- 最高位补符号位 //算术右移

无符号 --- 最高位补0 //逻辑右移

练习:

考题: 计算 一个int 类型中有多少个1

int a = 12134;

1100 0001

& 1


0000 0001

【练习】

编写程序实现循环左移

i<<2;

1000 0000

step1:从最高位移出一位

是0还是1

step2:将最高位的 这个 0 或者 1

塞到尾部

step3:左移几位

循环走几遍

1101 1111 1111 1111 1111 1111 1111 1111

d

1011 1111 1111 1111 1111 1111 1111 1111

b


相关推荐
Scott9999HH3 小时前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
码智社4 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海4 小时前
python 列表、元组、集合和字典
开发语言·python
萧瑟余晖5 小时前
JDK 26 新特性详解
java·开发语言
马优晨6 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
a1117767 小时前
2FA 验证码生成器(github登录验证 app)
笔记·学习
我的xiaodoujiao7 小时前
API 接口自动化测试详细图文教程学习系列32--Allure测试报告2
python·学习·测试工具·pytest
人邮异步社区8 小时前
怎么把C语言学到精通?
c语言·开发语言
心平气和量大福大8 小时前
C#-WPF-控件-TextBox 数据绑定
开发语言·c#·wpf
ttwuai8 小时前
Cursor 生成 CRUD 后,Go 后台接口别只测 200:JWT、RBAC 和 tenant_id 怎么验
开发语言·后端·golang