预处理详解(一) -- 预定义符号与#define定义


在这里插入图片描述

一. 预定义符号

%s _ _FILE_ _ //文件
%s _ _ DATE_ _ //日期
%s _ _ TIME_ _ //时间
%d _ _ LINE_ _ //行号
%d _ _ STDC_ _ //如果编译器支持 ANSI C,那么该值为1,
//否则未定义

在这里插入图片描述
在这里插入图片描述

二. #define

1.#define定义常量

define name stuff
#define定义常量在预处理阶段被替换成对应的内容(stuff)
// name:符号名
// stuff:符号内容

举个例子:

#define MAX 1000
#define reg registe
//使用reg 等同于使用 registe,还更为简洁
#define forever for(;;)
//初始化
//调整
//判断都可以省略不写
//但是判断不写,条件会恒为真,会造成死循环
int main()
{

	printf("%d\n", MAX);
	MAX直接被替换为1000

	return 0;
}

2.#define定义宏

#define name(parament-list) stuff
name:符号名
parament-list:是由逗号隔开的参数表,他们有可能出现在stuff中
stuff:符号内容 == 表达式
注意:
parament-list的左括号必须紧挨到name,不然parament-list会被识别为stuff中的内容

举个例子:

#define SQUARE(x) x*x

int main()
{
   int a = 10;
   printf("%d\n",SQUARE(a));//100
   printf("%d\n",SQUARE(a+1));//21
   
   return 0;
}

这里的 x = 10,1010 = 100
**a+1是直接进行替换,是a+1
a+1 = 2*a + 1 = 21
注意:
宏替换时不要吝啬括号,尽量能加括号的就加括号
所以加括号可以避免符号运算中出现不可预料的结果
那么这题正确是:#define SQUARE(x) ((x) * (x))

3.带有副作用的宏参数

宏的参数带有副作用就可能出现不可预料的结果

a + 1;//没有副作用
a++;//具有副作用

MAX可以证明带有副作用的宏

#define MAX(a,b) ((a>b) ? (a) : (b))
 
int main()
{
  int a = 1;
  int b = 2;
  int c = MAX(a++,b++);
  printf("%d %d %d",a,b,c);
  // a = 2 b = 4 c = 3
  return 0;
}

正确的写法:
在这里插入图片描述

4.宏替换的规则

1.在调用宏的时,首先对参数进行检查,检查是否有宏定义的符号,如果有,他们首先被替换
2.替换文本随后被插入到程序中原来文本的位置。
对于宏,参数名被他们的值所替换
3.最后再次对结果文件进行扫描,检查它是否还有#define定义的符号。如果是,就重复上述处理过程

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

#define MAX(a,MAX(2,3))//不是递归,是MAX的参数
#define MAX(x,y) MAX(x,y)//不能出现递归
//宏的内部调用了宏(表达式部分调用了宏)

2.当预处理器搜索#define出现的符号时,字符串常量并不被搜索

#define M 10
#define MAX(a,b) ((a>b) ? (a) : (b))
MAX(M,2);//M会被替换成10

printf("M = %d");//字符串常量不会被替换

5.宏和函数的对比

1.宏的优点:
通常被用于简单的运算
执行一条和函数有同样功能的语句,速度快,效率高
宏只有执行运算的时间,宏不存在内存的栈区静态区堆区,宏是不占用内存空间的
宏的参数无类型,所以宏可以进行任何类型的计算,是直接进行替换的
宏的参数可以出现类型:

#define MALLOC(num, type)\  // \为续行符,可以连接下一行
(type)malloc(num*sizeof(type))
...
//使⽤
MALLOC(10, int); //类型作为参数
//预处理器替换之后:
(int)malloc(10*sizeof(int));

2.宏的缺点:
宏会增加代码的长度,宏不能进行递归等等
3. 函数的优点:
函数会将值算好,才传参过去
在这里插入图片描述
4.函数的缺点:
函数的执行操作比较复杂,在反汇编中执行长度比较长
函数只能求特定类型的大小的运算等等

相关推荐

  1. # C语言——预处理(#define,#if..)

    2024-03-31 12:24:01       29 阅读

最近更新

  1. 源码编译安装LAMP

    2024-03-31 12:24:01       0 阅读
  2. 网格化监控:Eureka与分布式服务网格的协同监控

    2024-03-31 12:24:01       1 阅读
  3. Tomcat异步请求实现原理和应用场景简介

    2024-03-31 12:24:01       1 阅读
  4. [Python学习篇] Python面向对象——类

    2024-03-31 12:24:01       1 阅读
  5. 每日一道算法题 LCR 150. 彩灯装饰记录 II

    2024-03-31 12:24:01       1 阅读
  6. Ubuntu 添加so库搜索路径

    2024-03-31 12:24:01       1 阅读

热门阅读

  1. 用Lua控制Nginx静态文件的url访问权限

    2024-03-31 12:24:01       17 阅读
  2. Vue-前端应用开发平时作业第二章

    2024-03-31 12:24:01       15 阅读
  3. Ubuntu下udp通信

    2024-03-31 12:24:01       18 阅读
  4. es与mysql同步问题

    2024-03-31 12:24:01       21 阅读
  5. Leetcode 3. 无重复字符的最长子串

    2024-03-31 12:24:01       15 阅读
  6. 带头双向循环链表的实现及注释教学

    2024-03-31 12:24:01       15 阅读
  7. 面试碰到的一些问题

    2024-03-31 12:24:01       13 阅读
  8. PHP - ZipArchive上传、下载实例

    2024-03-31 12:24:01       17 阅读