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

news2024/12/24 8:37:10

目录

  • 一. 预定义符号
  • 二. #define
    • 1.#define定义常量
    • 2.#define定义宏
      • 3.带有副作用的宏参数
      • 4.宏替换的规则
      • 5.宏和函数的对比

在这里插入图片描述

一. 预定义符号

%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.函数的缺点:
函数的执行操作比较复杂,在反汇编中执行长度比较长
函数只能求特定类型的大小的运算等等

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1558180.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python基础——异常捕获【try-except、else、finally】

📝前言: 这篇文章主要介绍一下python基础中的异常处理: 1,异常 2,异常的捕获 3,finally语句 🎬个人简介:努力学习ing 📋个人专栏:C语言入门基础以及python入门…

[图解]DDD领域驱动设计伪创新-通用语言01

0 00:00:01,420 --> 00:00:04,110 今天我们来说一个 1 00:00:04,390 --> 00:00:07,450 领域驱动设计的伪创新,通用语言 2 00:00:12,780 --> 00:00:13,960 通用语言 3 00:00:14,460 --> 00:00:14,830 4 00:00:14,830 --> 00:00:15,940 英文叫 5 0…

Python | Leetcode Python题解之第2题两数相加

题目: 题解: # Definition for singly-linked list. # class ListNode: # def __init__(self, val0, nextNone): # self.val val # self.next next class Solution:def addTwoNumbers(self, l1: Optional[ListNode], l2: Optiona…

阿里云服务器经济型e实例特点、适用场景介绍和问题解答

阿里云服务器ECS经济型e系列是阿里云面向个人开发者、学生、小微企业,在中小型网站建设、开发测试、轻量级应用等场景推出的全新入门级云服务器,CPU处理器采用Intel Xeon Platinum架构处理器,支持1:1、1:2、1:4多种处理器内存配比&#xff0c…

ADC--数模转换器的使用

目录 前言 ADC接口使用 配置准备 确定引脚编号 光敏电阻--PF7​编辑 ADC3_IN5 开始配置 实验进阶 MQ_3--酒精传感器、水位传感器、火焰传感器 前言 ADC(analog-digital conversion)顾名思义模拟数字转换器,把外界的譬如温度、湿度、酒精含量、水位、特殊光波等等的现实…

小狐狸JSON-RPC:wallet_addEthereumChain(添加指定链)

wallet_addethereumchain(添加网络) var res await window.ethereum.request({"method": "wallet_addEthereumChain","params": [{"chainId": "0x64", // 链 ID (必填)"…

数据结构 - 算法效率|时间复杂度|空间复杂度

目录 1.算法效率 2.时间复杂度 2.1定义 2.2大O渐近表示法 2.3常见时间复杂度计算举例 3.空间复杂度 3.1定义 3.2常见空间复杂度计算举例 1.算法效率 算法的效率常用算法复杂度来衡量,算法复杂度描述了算法在输入数据规模变化时,其运行时间和空间…

6.5物联网RK3399项目开发实录-驱动开发之LCD显示屏使用(wulianjishu666)

90款行业常用传感器单片机程序及资料【stm32,stc89c52,arduino适用】 链接:https://pan.baidu.com/s/1M3u8lcznKuXfN8NRoLYtTA?pwdc53f LCD使用 简介 AIO-3399J开发板外置了两个LCD屏接口,一个是EDP,一个是LVDS,接口对应板…

Profinet转ModbusTCP:从站设备转换与集成案例

本案例旨在探讨如何将Modbus TCP设备数据成功地接入到西门子PROFINET网络中。为了实 现这一目标,我们将使用西门子S7-1200型PLC以及耐特森Profinet转ModbusTCP网关作为 关键设备。为了模拟Modbus从站,我们将使用电脑安装modbus poll软件。首先需要了解Pr…

PCL点云处理之重复随机采样一致性(RRANSAC法)平面拟合(二百三十七)

PCL点云处理之重复随机采样一致性(RRANSAC法)平面拟合(二百三十七) 一、算法介绍二、算法实现1.代码2.结果一、算法介绍 pcl::SAC_RRANSAC"是 PCL库中的一个方法,是 RANSAC 方法的改进版本,通过多次重复采样和模型拟合来提高鲁棒性。RRANSAC 的思想是在 RANSAC 的基…

从0开始搭建基于VUE的前端项目(一) 项目创建和配置

准备与版本 安装nodejs(v20.11.1)安装vue脚手架(@vue/cli 5.0.8) ,参考(https://cli.vuejs.org/zh/)vue版本(2.7.16),vue2的最后一个版本vue.config.js的配置详解(https://cli.vuejs.org/zh/config/)element-ui(2.15.14)(https://element.eleme.io/)vuex(3.6.2) (https://…

2024年天津仁爱学院退役大学生士兵专升本专业课报名确认安排

天津仁爱学院2024年高职升本科退役大学生士兵专业课报名确认及考试安排的通知 按照市高招办《2024年天津市高职升本科招生实施办法》(津招办高发〔2023〕14号)文件要求,天津仁爱学院2024年高职升本科退役大学生专业课考试报名、确认及考试工…

【C++】C到C++的入门知识

目录 1、C关键字 2、命名空间 2.1 命名空间的定义 2.2 命名空间的使用 2.2.1 加命名空间名称及作用域限定符 2.2.2 使用using将命名空间中某个成员引入 2.2.3 使用using namespace 命名空间名称引入 3、C输入&输出 4、缺省参数 4.1 缺省参数的概念 4.2 缺省参数的…

ctf.show_web

11.ctf.show_web11 解题步骤 密码为空,用 bp 抓包,去掉 session。 $password$_SESSION[password]:输入的password和session的结果一致 后端代码就是拿这个session的value值与我们输入的密码进行匹配, 由于这个value值我没解密出来, 所以这…

常用的6个的ChatGPT网站,国内可直接访问!

AIGC 🌐 链接:AIGC🏷️ 标签:AI绘图 AI聊天 GPT-4 免费 收费 需登录📝 简介:AIGC结合了ChatGPT与Midjourney,提供GPT-3.5、GPT-4及最新的Claude3模型。支持语音对话、识图、文档解析和联网等功…

Intellij IDEA 类注释模板设置

1、配置全局USER 在此配置全局USER,用于填充自动生成的注释中的作者author属性。 注释模板中的user参数是默认是获取系统的用户(当然注释作者也可以直接写固定值),如果不想和系统用户用同一个信息,可以在IDEA中进行配…

通过PandasAI使用自然语言进行数据分析

通过PandasAI使用自然语言进行数据分析 介绍 ​ PandasAI是一个Python库,可以很容易地用自然语言向数据提问。它可以帮助您使用生成人工智能来探索、清理和分析数据。 使用PandasAI 这里使用Anaconda和Jupyter使用PandasAI 进入一个文件目录 创建一个 Notebook …

31.Python从入门到精通—Python数据压缩 性能度量 测试模块

31.从入门到精通:Python数据压缩 性能度量 测试模块 个人简介数据压缩性能度量测试模块 个人简介 🏘️🏘️个人主页:以山河作礼。 🎖️🎖️:Python领域新星创作者,CSDN实力新星认证&#xff0c…

【3D-GS】Gaussian Splatting SLAM——基于3D Gaussian Splatting的全网最详细的解析

【3D-GS】Gaussian Splatting SLAM——基于3D Gaussian Splatting的定SLAM 3D-GS 与 Nerf 和 Gaussian Splatting1. 开山之作 Nerf2. 扛鼎之作 3D Gaussian Splatting2.1 什么是3D高斯?高斯由1D推广到3D的数学推导2.2 什么是光栅化?2.3 什么是Splatting?2.4 什么是交叉优化?…

QT中的文件操作QFile、QDataStream、QTextStream、QBuffer

文件操作概述 1、Qt中IO操作的处理方式 (1)、Qt通过统一的接口简化了文件与外部设备的操作方式 (2)、Qt中的文件被看做是一种特殊的外部设备 (3)、Qt中的文件操作与外部设备操作相同 2、IO操作中的关键…