嵌入式基础学习|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 name[20];

int sno;

float score;

};

struct teacher

{

char name[20];

int tno;

float salary;

};

struct member

{

char name[20];

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 ip[4];

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_t[4]; //一维数组

array_t b[3]; //array_t => int[4]

位运算:

指的是二进制位上的运算

用途:

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

操作硬件

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


相关推荐
kk努力学编程2 分钟前
Linux基础14-C语言篇之变量与标识符【入门级】
java·linux·c语言
蹦蹦跳跳真可爱58914 分钟前
Python----PyQt开发(PyQt基础,环境搭建,Pycharm中PyQttools工具配置,第一个PyQt程序)
开发语言·python·pyqt
逆鱼_0441 分钟前
C语言-结构体
c语言·开发语言
倔强的石头1061 小时前
【C++指南】解锁C++ STL:从入门到进阶的技术之旅
开发语言·c++
嗷嗷哦润橘_1 小时前
Deepseek系列从v3到R易背面经版
开发语言·人工智能·笔记·deepseek
霜雪殇璃1 小时前
(定时器,绘制事件,qt简单服务器的搭建)2025.2.11
运维·服务器·qt·学习
bitenum1 小时前
【C/C++】位段
c语言·数据结构·c++·算法·青少年编程
nqqcat~1 小时前
集合7天学java—day2
java·开发语言
if就1 小时前
Java_多线程
android·java·开发语言
后端小肥肠1 小时前
FastExcel + Java:打造高效灵活的Excel数据导入导出解决方案
java·开发语言·spring boot·后端·excel