#define 的使用

本文详细介绍了C语言中的#define宏定义,包括不带参数和带参数的宏定义,强调了宏定义的注意事项,如参数括号的重要性,以及与函数的区别。还探讨了#define中的#、##操作符的用法,并解释了do{}while(0)结构在宏定义中的作用,最后提到了C语言库中的一些宏用于提供编译信息。

前言
1、本人QQ – 330952038 欢迎一起学习交流。
2、#define 的用法,相信大家有用过,本文抱着学习的态度来重新理解#define(宏定义)

正文
一、不带参数的宏定义
eg: #define BUF_MAX_LEN 100 // 定义 BUF_MAX_LEN为 100,此时就可以把BUF_MAX_LEN当做100使用。
unsigned char *buf[BUF_MAX_LEN ] ; // 申请一个100字节数组

注意:
1) 宏定义习惯用大写字母表示(只是建议并非强制)
2) 宏定义可以提高通用性,比如上面例子,可能被多处引用,只需要改变BUF_MAX_LEN 大小就可以改变所有被调用的地方
3) 宏定义不是C语言语句(宏定义需要通过预处理后转换成C语句), 不需要加入分号,所以声明时不能在末尾加入分号,否则会有导致使用时出现语法出错
eg: #define a 10;
unsigned char b = a*5; —-> (10;)*5 — 会导致语法错误

二、带参数的宏定义
#define 宏名(参数表) 字符串
eg: #define fun(x,y) (x)*(y)
area = fun(2,3); // 该功能相对于 area = (2)*(3);

注意
1)
带参数的宏定义,在后面的表达式中,参数最好是带上括号!
上面(x)*(y) 这两个参数为什么要加入括号呢?因为实参去替换形参时,并不会自动转换成你要的结果,而是原样替换。
比如 #define fun(x,y) x*y
char a = 4, b =3;
area = fun(a+b,a-b);
那么结果会是: area = a+b*a-b;
所以使用这种形式时,千万别忘记加入括号。

2)
在定义宏时,在宏名和带参数的括号之间不能加空格,否则将空格以后的字符都作为替代字符串的一部分,如:
#define S (r) r*r
area = S(a);
则area = (r) r*r(a);// 这是个错误的表达式

3)
很多人把带参数的宏定义和函数混淆。下面我们介绍一下两者区别:
a) 函数调用时,先求出实参表达式的值才会进行代入形参,而使用带参数的宏定义只是进行替换。
eg:

#define fun1(x,y)  x*y
#define fun2(x,y)  (x)*(y)
u8 fun3(u8 x,u8 y)
{
   return x*y;
}
int main()
{
   u8 a = 3,b = 2;
   u8 t1,t2,t3;

   t1 = fun1(a+b,a-b);// 直接进行替换形参,则t1 = a+b*a-b = 7
   t2 = fun2(a+b,a-b);// 直接进行替换形参,则t2 = (a+b)*(a-b) = 5
   t3 = fun3(a+b,a-b);// 先计算实参表达式值,即a+b = 5, a-b = 1,然后代入形参,计算结果是 t3 = 5*1;
   while(1);
}

b) 对函数中的实参和形参都要定义类型,二者的类型要求一致,如果不一致,需要进行类型转换。而宏不存在这样的问题,宏名无类型,他的参数也是无类型,只是一个符号代表。置换时,代入指定的字符串即可。定义宏时,可以是任何类型的数据
eg: #define num 1.23 // 数值
#define name “zhangsan” // 字符串

上面num和name不需要定义类型,它们不是变量,程序中用到num或者name时就会进行替换。
上面name定义为一个字符串,在预处理时,就会为num分配一个代码段的地址存储该字符串,而num本身可以理解为一个cha

在C/C++中,`#define` 和 `if` 是两种不同类型的语法元素,分别用于预处理和程序运行时逻辑判断,下面介绍它们的使用方法和场景。 ### `#define` 的使用方法和场景 #### 使用方法 `#define` 用于定义,有两种常见形式:定义标识符和带参数的- 定义标识符:基本形式为 `#define 标识符 值`。预处理时,源代码中出现的该标识符会被替换成对应的值。例如: ```c #define MAX 1000 ``` 这里定义了一个名为 `MAX` 的,值为 `1000`。在后续代码中,所有 `MAX` 都会被替换成 `1000`。 - 带参数的:基本形式为 `#define 名(参数列表) 替换体`。例如用 `#define` 实现求最大值的: ```c #define MAX(a, b) ((a) > (b) ? (a) : (b)) ``` 在代码中使用 `MAX(x, y)` 时,会将 `a` 替换为 `x`,`b` 替换为 `y` 进行计算。 #### 场景 - 定义常量:可以用 `#define` 定义常量,不过C++更推荐使用 `const` 关键字。例如 `#define PI 3.14159` [^1]。 - 简化代码:为一些较长的关键字或代码片段创建简短的名字,提高代码可读性。如 `#define reg register`,用 `reg` 代替 `register` 关键字 [^3]。 - 条件编译:结合 `#if`、`#elif`、`#else` 和 `#endif` 指令进行条件编译。例如: ```c #define DEBUG #ifdef DEBUG // 调试代码 #else // 发布代码 #endif ``` 这段代码根据是否定义了 `DEBUG` 来决定编译调试代码还是发布代码 [^2]。 - 平台兼容性:通过条件编译适配不同平台。例如: ```c #ifdef _WIN32 #define OS_WINDOWS #elif defined(__linux__) #define OS_LINUX #endif ``` 根据不同的操作系统定义不同的,方便代码在不同平台上编译 [^4]。 ### `if` 的使用方法和场景 #### 使用方法 `if` 语句用于程序运行时的条件判断,基本形式有以下几种: - 简单 `if` 语句: ```c if (条件表达式) { // 条件为真时执行的代码 } ``` - `if-else` 语句: ```c if (条件表达式) { // 条件为真时执行的代码 } else { // 条件为假时执行的代码 } ``` - `if-else if-else` 语句: ```c if (条件表达式1) { // 条件1为真时执行的代码 } else if (条件表达式2) { // 条件2为真时执行的代码 } else { // 以上条件都为假时执行的代码 } ``` #### 场景 - 程序逻辑判断:根据不同的条件执行不同的代码块。例如根据用户输入的值进行不同的处理: ```c int num; scanf("%d", &num); if (num > 0) { printf("输入的数是正数\n"); } else if (num < 0) { printf("输入的数是负数\n"); } else { printf("输入的数是零\n"); } ``` - 循环控制:在循环中使用 `if` 语句来控制循环的执行。例如在 `for` 循环中提前结束循环: ```c for (int i = 0; i < 10; i++) { if (i == 5) { break; } printf("%d ", i); } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值