当前位置 博文首页 > CW_qian的博客:8月22日笔记C语言基础(补3)宏定义与条件编译2
1.预处理
?? ?程序在编译之前,是由预处理器CC1先检查c文件有没有以#号开头的符号称为宏
?? ?如果有,CC1是不会做任何的逻辑判断直接将里里面的内容替换出来,或者拷贝出来
?? ?我们把这种方式称为宏展开
?? ?
预处理指令(宏)包括
?? ?1.头文件 #include?
?? ?2.定义宏 #define
?? ?3.取消 #undef
?? ?4.条件编译 #if #ifdef #ifndef #else #elif #endif
?? ?5.向编译器发送指令 #pragma
?? ??? ?#pragma pack(1) // 设置结构体M值的大小
?? ??? ?加载库
?? ??? ?
2.宏的概念
?? ?宏其实就是一段特定的字符串,在预处理的时候会被替换
?? ?
3.宏的分类
?? ?1.无参宏之自定义宏
?? ??? ?无参宏的意思是使用的时候无需指定任何的参数
?? ?例如:?
?? ??? ?#define PI 3.14
?? ??? ?#define LCD_SIZE 800*480*4
?? ??? ?
?? ?注意:此处的PI表示宏,一般使用大写字母表示,用于区分变量和函数,当然这不是
?? ??? ?语法规定,只是个人习惯而已
?? ??? ?
?? ?2.无参宏之系统宏
?? ??? ?#define O_RDONLY : 0x1?
?? ??? ?#define O_WRONLY : 0X2
?? ??? ?#define NULL ((void *)0) char *p = NULL 等价于 char *p = (void *)0;
?? ??? ?
?? ?3.带参宏
?? ??? ?带参宏意味着宏定义是可以带参数的,从形式上看是和函数很像
?? ??? ?
?? ??? ?#define MAX(a,b) a>b ? a : b?
?? ??? ?#define MIN(a,b) a<b ? a : b?
?? ??? ?
?? ?4.带参数的宏的特点:
?? ??? ?1.直接文本替换,不做任何的语法判断,不做任何的中间转换
?? ??? ?2.宏在预编译的时候已经被替换了,所以运行的时候不存在宏
?? ??? ?3.宏展开的时候浪费了内存空间,但是节约了程序运行的时间
?? ??? ?
?? ?5.带参宏的问题解决方式:
?? ??? ?//#define MAX(a,b) a>b ? a : b // 容易出bug 解决方法如下
?? ??? ?#define MAX(a,b) ((a)>(b) ? (a) : (b))
?? ?
?? ?6.无值的宏
?? ??? ?#define _MYHEAD_H
?? ??? ?#define WIN_32
?? ??? ?#define WIN_64
?? ??? ?
?? ??? ?无值宏一般是头文件或者在编译中作为判断条件出现
?? ??? ?
?? ?7.总结
?? ??? ?1.宏是用于替换指定的表达式,增加代码的可读性
?? ??? ?2.使得程序修改比较方便,如果程序有多个地方使用到宏的时候,只需要修改宏定义即可
?? ??? ?3.提高程序的运行效率
2.条件编译
?? ?是用来控制编译器编译哪一段代码
?? ?#if? ? ? ? ? ? ? ? 如果条件为真,则执行相应的操作,可以起到类似于注释的效果
?? ?#elif? ? ? ? ? ? ?如果前面的为假,那么执行此语句
?? ?#else? ? ? ? ? ?如果前面的操作都为假,则执行以下语句
?? ?#endif? ? ? ? ? 结束条件编译
?? ?#ifdef? ? ? ? ? ?如果改宏已经被定义则执行相应的操作
?? ?#ifndef ????????如果宏没被定义,则执行相应的操作
?? ?
?? ?#if -- #else -- #endif
?? ?格式如下:
?? ?#if 条件表达式
?? ??? ?代码段1
?? ?#else
?? ??? ?代码段2
?? ?#endif
?? ?demo:
? ??? ?#define DEBUG 1
?? ??? ?int main()
?? ??? ?{
?? ??? ??? ?#if 0 // 0 为假
?? ??? ??? ??? ?printf("此处为假\n");
?? ??? ??? ?#else
?? ??? ??? ??? ?printf("此处为真\n");
?? ??? ??? ?#endif
?? ??? ??? ?
?? ??? ??? ?#if DEBUG //DEBUG 为真
?? ??? ??? ??? ?printf("此处为真\n");
?? ??? ??? ?#else
?? ??? ??? ??? ?printf("此处为假\n");
?? ??? ??? ?#endif // 结束
?? ??? ??? ?return 0;
?? ??? ?}
? 条件编译,多路分支
?? ?#if -- #elif -- #elif -- #endif
?? ?#define A 1
?? ?#define B 2
?? ?#define C 3
?? ?//-----------------
?? ?#if A
?? ??? ?printf("A\n");
?? ?#elif B
?? ??? ?printf("A\n");
?? ?#elif C
?? ??? ?printf("A\n");
?? ?#endif?? ?
??
? ? 检测程序中如果没有定义宏则定义
?? ?#ifndef --- #define --- #endif
?? ?定义格式
?? ??? ?#ifndef 标识符
?? ??? ?#define 标识符 替换列表
?? ??? ?#endif
?? ?demo:
?? ??? ?#define PI 3.1415
?? ??? ?#ifndef PI
?? ??? ?#define PI 3.14
?? ??? ?#endif
? ?运用场景主要是头文件
? ? 检测如果定义了宏则删除
?? ?#ifdef -- #undef -- #endif
?? ?定义格式:
?? ??? ?#ifdef 标识符
?? ??? ??? ?代码段1
?? ??? ?#endif
?? ?demo:
?? ??? ?#define N 456
?? ??? ?#ifdef N
?? ??? ?#undef N
?? ??? ?#define N 123
?? ??? ?#endif
? ?条件编译的使用场景
?? ?在程序中,用条件编译将调试语句包裹起来,通过gcc编译器来选择编译哪一段
?? ?代码
?? ?int main()
?? ?{
?? ??? ?#ifdef A // 现在没有定义此宏
?? ??? ??? ?printf("A\n");
?? ??? ?#else
?? ??? ??? ?printf("haha\n");
?? ??? ?#endif
?? ??? ?
?? ?}
?? ?编译方法:
?? ??? ?gcc main.c -o main -DA // -D 的意思是编译程序的时候定义哪一个宏
?? ??? ?
作业:
?? ?现有一个嵌入式设备终端传输过来的数据包是一个32位无符号的整型数,这个数据包里面各位含义如下:
?? ?00-07位:表示温度数据
?? ?08-15位:表示湿度数据
?? ?16-19位:表示4扇门状态(门的编号0-3) ? ? ?二进制:0001 ?0010 0100 1000 ? 十六进制 1 2 4 8
?? ?20-23位:表示四盏灯的状态(灯编号0-3)
?? ?24-31位:预留备用
?? ?下面是最近一段时间接受的数据包:
?? ?0x12344520, 0xff004B1C,0x00553C1E
?? ?请编写一个程序接收这3个数据包,并解析出对应的数据【温度,湿度,门0-3,灯0-3】(门和灯的状态0-关,1-开)。
?? ?
?? ?使用宏来实现以上功能:
?? ?提示
?? ?#define TEMP_MASK 0x000000FF
?? ?#define HUMI_MASK 0x0000FF00
?? ?
?? ?#include <stdio.h>
?? ?#define TEMP_MASK 0x000000FF
?? ?#define HUMI_MASK 0x0000FF00
?? ?
?? ?#define TEMPERATURE(a) ((a&TEMP_MASK) >> 0)
?? ?#define HUMIDITY(a) ?((a&HUMI_MASK) >> 8)
?? ??? ?
?? ?#define DOOR0_MASK 0x00010000
?? ?#define DOOR1_MASK 0x00020000
?? ?#define DOOR2_MASK 0x00040000
?? ?#define DOOR3_MASK 0x00080000
?? ?
?? ?#define LIGHT0_MASK 0x00100000
?? ?#define LIGHT1_MASK 0x00200000
?? ?#define LIGHT2_MASK 0x00400000
?? ?#define LIGHT3_MASK 0x00800000
?? ?
?? ?int main()
?? ?{
?? ??? ?unsigned int data;
?? ??? ?printf("请输入接收到的数据:\n");
?? ??? ?while(1)
?? ??? ?{
?? ??? ??? ?scanf("%x",data);
?? ??? ??? ?
?? ??? ??? ?printf("温度: ?%d\n",TEMPERATURE(data));
?? ??? ??? ?printf("湿度: ?%d\n",TEMPERATURE(HUMIDITY));
?? ??? ??? ?
?? ??? ??? ?printf("门0: %s\t",(data & DOOR0_MASK) ? "开":"关");
?? ??? ??? ?printf("门1: %s\t",(data & DOOR1_MASK) ? "开":"关");
?? ??? ??? ?printf("门2: %s\t",(data & DOOR2_MASK) ? "开":"关");
?? ??? ??? ?printf("门3: %s\t",(data & DOOR3_MASK) ? "开":"关");
?? ??? ??? ?
?? ??? ??? ?printf("灯0: %s\t",(data & LIGHT0_MASK) ? "亮":"灭");
?? ??? ??? ?printf("灯1: %s\t",(data & LIGHT1_MASK) ? "亮":"灭");
?? ??? ??? ?printf("灯2: %s\t",(data & LIGHT2_MASK) ? "亮":"灭");
?? ??? ??? ?printf("灯3: %s\t",(data & LIGHT3_MASK) ? "亮":"灭");
?? ??? ??? ?
?? ??? ?}
?? ??? ?
?? ?}