嵌入式基础学习|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


相关推荐
程序员良辰3 分钟前
服务器 JDK 环境变量配置:一键安装和手动配置有什么区别?
开发语言·python
小弥儿9 分钟前
GitHub今日热榜 | 2026-09-01:迷你小模型登场
学习·microsoft·开源·github
奈斯先生Vector10 分钟前
本地图片识别怎么接入多模态 AI?用 Python API 理解 GPT-4o Vision 的真实工作流
开发语言·人工智能·windows·python·网络协议·http·aigc
高亦真13 分钟前
今天是学习嵌入式的第33天
linux·学习·算法
OPEN-F14 分钟前
C++17新特性精讲:结构化绑定、if constexpr与实用类型
开发语言·c++
OPEN-F17 分钟前
C++并发编程:线程与互斥锁
开发语言·c++
俊昭喜喜里19 分钟前
C#中的decimal
开发语言·c#
catchadmin29 分钟前
免费可商用 PHP 管理后台 CatchAdmin V5.4.0 发布,新增短信服务能力
开发语言·php
在线考试系统推荐38 分钟前
拆成多道小题,优考试“理解题“怎么用?
服务器·人工智能·学习
小白学大数据40 分钟前
API 调用错误处理实战:分层定位、有纪律地重试与可观测性设计
开发语言·网络·人工智能