#define定义宏

本文详细介绍了C语言中#define宏的使用,包括宏定义的基本语法,如参数列表和字符串替换,以及宏替换的规则、代码块替换、条件编译和潜在的副作用。通过实例演示了如何在代码中正确运用宏以提高效率和代码组织
摘要由CSDN通过智能技术生成

基本语法:

#define name( parament-list ) stuff

其中的 parament-list 是⼀个由逗号隔开的符号表,它们可能出现在stuff中。

简单的说就是和函数差不多,在宏里面写一个类似于函数的计算方法,但是比函数运行的速度要快。

#define宏替换的使用

 在C语言中,`#define` 预处理器指令用于定义宏,这些宏可以在编译时被预处理器替换为指定的文本。

下面是一些使用 `#define` 宏替换的例子:

1. **定义一个简单的宏**:
   ```c
   #define PI 3.14159
   #define MIN(a, b) ((a) < (b) ? (a) : (b))
   #define SQUARE(x) ((x) * (x))
   ```
   在这些例子中,`PI` 被定义为圆周率的值,`MIN` 宏接受两个参数并返回它们中的最小值,`SQUARE` 宏接受一个参数并返回其平方。
2. **使用宏替换字符串**:
   ```c
   #define GREETING "你好,世界!"
   ```
   这个宏可以在代码中任何需要字符串 "你好,世界!" 的地方使用。
3. **使用宏替换代码块**:
   ```c
   #define PRINT_INT(i) printf("整数:%d\n", i)
   ```
   这个宏可以在代码中任何需要打印整数的地方使用。
4. **在宏中使用续行符号**:
   ```c
   #define LONG_MACRO(x, y) x ## y \
                            x ## _ ## y \
                            y ## _ ## x
   ```
   这个宏使用了续行符号 `\` 来将宏的定义延续到下一行。它将生成三个串联的字符串。
5. **在宏中包含条件编译**:
   ```c
   #define DEBUG 1
   #if DEBUG
   #define LOG(msg) printf("调试信息:%s\n", msg)
   #else
   #define LOG(msg)
   #endif
   ```

这里我们主要讲解1,4。因为2,3,5基本上就是定义常量,直接进行替换就可以。
下面是一个完整的例子,展示了如何在 `main` 函数中使用这些宏:

```c
#include <stdio.h>
#define PI 3.14159
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define SQUARE(x) ((x) * (x))
#define GREETING "你好,世界!"
#define PRINT_INT(i) printf("整数:%d\n", i)
int main() {
    double radius = 10.0;

    double area = PI * SQUARE(radius);//

    printf("圆的面积是:%.2f\n", area);
    int a = 5;
    int b = 10;

    PRINT_INT(MIN(a, b));

    printf(GREETING "\n");
    return 0;
}
```

使用详解1

在这个例子中,我们使用了多个宏来简化代码,并提高了代码的可读性和可维护性。

宏定义,也就是squart(x) 就散是x乘x

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#define MUL(x) ((x)*(x)) 
//宏的使用有很多小的点
//1,宏是直接进行替换的,所以在需要进行宏运算的时候,要尽量多加上括号,防止因为优先级的问题导致使用错误
int main()
{
	int a = 3;
	int ret = MUL(a);
	printf("%d ", ret);
	return 0;
}

使用详解2

这里打印出来是7

宏是直接替换的 这里就变成了3+1*3+1=3+3+1=7

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#define MUL(x) ((x)*(x)) 
#define MULL(x) x+1*x+1
//宏的使用有很多小的点
//1,宏是直接进行替换的,所以在需要进行宏运算的时候,要尽量多加上括号,防止因为优先级的问题导致使用错误
int main()
{
	int a = 3;
	int ret = MUL(a);
	int ret1 = MULL(a);

	printf("%d %d", ret, ret1);
	return 0;
}

预处理阶段宏定义

我们这里看一下预处理

如果想变成36 我们可以加上括号

所以可以书写乘((x)*(X))这样 书写宏的时候不要吝啬括号

所以

————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

#define的副作用 (带有副作⽤的宏参数)

++是有副作用的 这就是带有副作用

x+1;//不带副作⽤
x++;//带有副作⽤

副作用宏举例1

这里解释一下为什么有副作用

就比如下面的这个例子 ,首先什么定义一个宏,这里是一个三目操作符。如果我们传递的时候,把++传递过去就会导致宏的直接替换。

#define MAX(a, b) ( (a) > (b) ? (a) : (b) )
x = 5;
y = 8;
z = MAX(x++, y++);
printf("x=%d y=%d z=%d\n", x, y, z);//输出的结果是什么?

也就是变成了

1,我们要先把++,替换进去。

2,z = ( (x++) > (y++) ? (x++) : (y++));已知 x = 5;y = 8;

3,得到z = ( (x=5++) > (y=8++) ? (x++) : (y++));这里因为是后置++,所以是先比较后++,5大于8

4,所以此时x=6,y=9,但是这里是一个三目操作符,所以会导致的情况就是满足y++的条件,所以z=(y=8++)++=9,。

5,因为后置++,就是这个运算结束之后才会进行++,这里y++两次,所以y=10,进行z判断的时候,y++一次,所以z=9

6,这里我们需要知道,++是会改变数值的,也就是++上去的数值,数值是会进行变化的

z = ( (x++) > (y++) ? (x++) : (y++));
x=6 y=10 z=9

宏替换的潜规则

这里还是拿上个例子来进行举例 

这里每一次都进行++

这里我们看一下预处理阶段发生的事情

‘M’这里的字符在预处理阶段是不会被搜索到的,哪怕定义了宏M 

宏替换的规则

在程序中扩展#define定义符号和宏时,需要涉及⼏个步骤。

1. 在调⽤宏时,⾸先对参数进⾏检查,看看是否包含任何由#define定义的符号。如果是,它们⾸先

被替换。

2. 替换⽂本随后被插⼊到程序中原来⽂本的位置。对于宏,参数名被他们的值所替换。

3. 最后,再次对结果⽂件进⾏扫描,看看它是否包含任何由#define定义的符号。如果是,就重复上

述处理过程。

注意:

1. 宏参数和#define 定义中可以出现其他#define定义的符号。但是对于宏,不能出现递归。

2. 当预处理器搜索#define定义的符号的时候,字符串常量的内容并不被搜索。

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值