嵌入式课程day18-C语言共用体、枚举、宏定义、条件编译

devtools/2024/11/26 19:06:15/

目录

十二、共用体、枚举、宏定义、条件编译

12.1共用体

12.2枚举

12.3宏定义 

12.4条件编译


十二、共用体、枚举、宏定义、条件编译

12.1共用体

1多个成员共用同一块内存,

2所有成员的首地址都是一样的。

3共用体类型占据空间大小是里面占用空间最多成员所占字节数,同时也要满足是 分配单位 整数倍。

定义共用类型:
union 共用体名
{成员类型 成员名;成员类型 成员名;.....
};共用体类型:union 共用体名union data
{char ch;int a;
};// 共用体类型名称:union dataprintf ("%d", sizeof (union data));  // 4union data1
{char name[21];int b;
};printf ("%d", sizeof (union data));  // 24

共用体变量:

union data d1;//点语法
//d1.ch   &d1.ch
//d1.a    &d1.a#include<stdio.h>union data
{char ch;int a;
};int main (void)
{// 数据类型大小 printf ("%d\n", sizeof (union data));// 如何看成员在内存分布union data d1;printf ("%p %p\n", &(d1.ch), &(d1.a));d1.a = 0x12345678;printf ("%x\n", d1.ch);  // 0x78d1.ch = 0xaa;printf ("%x\n", d1.a);  // 0x123456aa;return 0;
}

应用场景:

1、可以将多字节的数据一个一个取出来
#include<stdio.h>union data
{unsigned int a;unsigned char arr[4];
};int main (void)
{union data d1;d1.a = 0x12345678;printf ("%x %x %x %x\n", d1.arr[3], d1.arr[2], d1.arr[1], d1.arr[0]);return 0;
}2、结合位域 -- 结构体可以将一个数据的每一位取出来
位域 -- 结构体strcut 结构体名
{成员类型 成员名 : 2;    // 2--2位 是位域的意思成员类型 成员名 : 2;...
};需求:8位的数据需要取出来数据的每一位,而且不开额外的空间。union SplitByte
{unsigned char a;struct BIT{unsigned char a0 : 1;unsigned char a1 : 1;unsigned char a2 : 1;unsigned char a3 : 1;unsigned char a4 : 1;unsigned char a5 : 1;unsigned char a6 : 1;unsigned char a7 : 1;}bits;
};int main ()
{union SplitByte b1;b1.a = 0xae;  // 10101110printf ("%d %d %d %d %d %d %d %d\n", b1.bits.a7, b1.bits.a6, b1.bits.a5, b1.bits.a4, b1.bits.a3, b1.bits.a2, b1.bits.a1, b1.bits.a0);return 0;
}

12.2枚举

罗列一些大写标识符,当做整型数据来使用, 代码易读。

枚举标识符如果没有赋值,默认从0开始,后面项依次增加1.

枚举标识符有赋值就用赋的数值,后面项没有赋值的依然是在前一项依次增加1.

enum 枚举名称
{标识符1, 标识符2, ......
};  // 枚举类型:enum 枚举名称举例:
罗列星期英文 当做星期数字使用。enum week
{MON, TUES, WEDS, THIR, FRI, SAT, SUN
};  // 0 1 2 3 4 5 6 代码:
#include<stdio.h>enum week
{MON = 1, TUES = 15, WEDS = 10, THIR = 19, FRI, SAT, SUN
};  // 1 15 10 19 20 21 22int main (void)
{printf ("%d %d %d %d %d %d %d\n", MON, TUES, WEDS, THIR, FRI, SAT, SUN);enum week a;  // 定义变量 printf ("%d", sizeof (enum week));  // 4return 0;
}

12.3宏定义 

定义一个标识符名 可以代表常量 、变量 、表达式  、 数据类型 .

 在 预处理阶段 进行宏替换。

1、标准宏

2、带参宏

格式:
#define  宏名  代表内容例子:
#define PI 3.1415926
#define BOOKNUM 100// 求一个半径为3的圆的面积
// π*r*rfloat area = PI * 3 * 3;  // 3.1415926 * 3 *3
printf ("%f", area);// 开BOOKNUM个结构体数组
BK arr[BOOKNUM];例子:
写一个宏,代表 a + b的和#include<stdio.h>#define ADD a+b
#define ADD1 (a+b)int main ()
{int a = 20;int b = 30;int res = ADD;  // int res = a + b;printf ("%d\n", res);int res1 = 2 * ADD; // int res1 = 2 * a + b; = 2*20+30 = 70printf ("%d\n", res1);int res2 = 2 * ADD1;  // int res2 = 2*(a+b); = 2*(20+30) = 100printf ("%d\n", res2);return 0;
}注意:
一般用宏名代表某一个表达式的时候,我们会用 ()将表达式包裹起来。
#define ADD1 (a+b)

12.4条件编译

根据不同的条件生成不同的目标代码

#if 常量 
代码块
#endif
#if 1#include<stdio.h>#define LED1_ON  printf("on")
#define LED1_OFF printf("off")int main (void)
{int res;scanf ("%d", &res);if (res == 1){LED1_ON;}else{LED1_OFF;}return 0;
}#endif
#if 常量
代码块1
#else
代码块2
#endif
#include<stdio.h>int main (void)
{printf ("串口1的配置\n");#if 0printf ("发送代码\n");
#elseprintf ("接受端的代码");
#endif printf ("串口1的关闭\n");return 0;
}// 常量为真 -- 目标代码 
// printf("串口1的配置\n");
// printf("发送代码\n");
// printf("串口1的关闭\n");// 常量为假 -- 目标代码 
// printf("串口1的配置\n");
// printf("接受端的代码\n");
// printf("串口1的关闭\n");通过条件编译可以节省代码区的代码,一份代码可以维护两个端。
#ifdef 宏名
代码块
#endif如果定义了宏名 ,就将代码块打包到目标代码里面去。
如果没有定义了宏名 ,就不打包。#include<stdio.h>#define RECVint main (void)
{printf ("串口1的配置\n");#ifdef RECVprintf ("接收端代码\n");
#endif printf ("串口1的关闭\n");return 0;
}
#ifndef 宏名
#define 宏名
代码块
#endif#ifndef _LED_H
#define _LED_H// 宏定义 类型定义 
#define LED1_ON printf("yes") typedef struct student
{int bno;char name[20];
}STU;// 函数声明 
void led_init (void);#endif

http://www.ppmy.cn/devtools/137192.html

相关文章

英语知识网站开发:Spring Boot框架技巧

摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了英语知识应用网站的开发全过程。通过分析英语知识应用网站管理的不足&#xff0c;创建了一个计算机管理英语知识应用网站的方案。文章介绍了英语知识应用网站的系…

macOS上进行Ant Design Pro实战教程(一)

由于一个AI项目的前端使用了umi&#xff0c;本教程根据阿里官网上的 《Ant Design 实战教程&#xff08;beta 版&#xff09;》来实操一下&#xff0c;我使用macOS操作系统&#xff0c;VS Code 开发环境。 一、开发环境 1、安装nodejs, npm, yarn 官网上建议使用cnpm&#xf…

使用Ansible/SaltStack编写自动化运维脚本

Ansible 或SaltStack 编写自动化运维脚本时&#xff0c;目标是通过模块化、参数化、可复用的方式来实现自动化运维任务。以下是编写自动化脚本的详细流程和示例。 Ansible Ansible 使用 YAML 格式编写任务&#xff0c;称为Playbooks。它基于无代理架构&#xff0c;通过 SSH 与…

第三十九章:Grafana 概述、Docker安装与验证指南

Grafana 概述、Docker安装与验证指南 一、Grafana 概述 Grafana 是一个跨平台的开源可视化分析工具,是目前网络架构和应用分析中最流行的时序数据展示工具。它主要用于大规模指标数据的可视化展示,并支持多种数据源和丰富的可视化插件。Grafana 使用Go语言开发,具备数据监…

基于Opencv的图像处理软件

目录 一、背景及意义介绍背景意义 二、概述一、背景及意义介绍背景意义 三、论文思路解决问题 四、复现过程&#xff08;一&#xff09;图像处理模块二&#xff09;图形界面模块&#xff08;一&#xff09;图像处理模块实现步骤&#xff08;二&#xff09;图形界面模块实现步骤…

企业OA管理系统:Spring Boot技术架构与应用

3系统分析 3.1可行性分析 通过对本企业OA管理系统实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本企业OA管理系统采用SSM框架&#xff0c;JAVA作为开发语言&a…

【LeetCode面试150】——228汇总区间

博客昵称&#xff1a;沈小农学编程 作者简介&#xff1a;一名在读硕士&#xff0c;定期更新相关算法面试题&#xff0c;欢迎关注小弟&#xff01; PS&#xff1a;哈喽&#xff01;各位CSDN的uu们&#xff0c;我是你的小弟沈小农&#xff0c;希望我的文章能帮助到你。欢迎大家在…

DICOM图像处理:深入解析DICOM彩色图像中的Planar配置及其对像素数据解析处理的实现

引言 在DICOM(Digital Imaging and Communications in Medicine)标准中,彩色图像的存储与显示涉及多个关键属性,其中**Planar Configuration(平面配置)**属性(标签 (0028,0006))尤为重要。当遇到彩色DICOM图像在浏览时被错误地分割为9张小图,而实际应显示为一…