预编译(1)

目录

预定义符号:

使用:

结果:

预编译前后对比:

#define定义常量:

基本语法:

举例1:

结果:

预编译前后对比:

 举例2:

预编译前后对比:

 注意事项:

#define定义宏:

下⾯是宏的申明⽅式:

举例:

使用:

 预编译前后对比:

 结果:

 注意事项:

1.参数列表的左括号必须与name紧邻,如果两者之间有任何空白存在,参数列表就会被解释为stuff的一部分。

举例:

正确的:

错误的:

2.不够严谨的写法导致的失误:

举例:

结果:

使用预编译进行查看替换的情况:

所以严谨的写法应该是:

带有副作用的宏:

 举例:

 当我们使用a++和b++这种带有永久性的效果时:

 预编译前后对比:​编辑

结果:

分析:

宏的替换规则:


预定义符号:

C语⾔设置了⼀些预定义符号,可以直接使⽤,预定义符号也是在预处理期间处理的。

__FILE__ //进⾏编译的源⽂件
__LINE__ //⽂件当前的⾏号
__DATE__ //⽂件被编译的⽇期
__TIME__ //⽂件被编译的时间
__STDC__ //如果编译器遵循ANSI C,其值为1,否则未定义

使用:

int main()
{ printf("%s\n", __FILE__);printf("%d\n", __LINE__);printf("%s\n", __DATE__ ;printf("%s\n", __TIME__);
}

结果:

 

预编译前后对比:

 

#define定义常量:

基本语法:

#define name stuff

举例1:

int main()
{int a = Mprintf("%d\n",M);printf("%s\n",STR);return 0 :
}
结果:

 

预编译前后对比:

 

 举例2:

#define forever for( ; ; )
int main()
{int a = M;printf("%d\n",M);printf("%s\n",STR);forever;return 0;
}

结果是无限循环

预编译前后对比:

 

 注意事项:

在define定义标识符的时候,不要在最后加上 ;  

#define定义宏:

#define 机制包括了⼀个规定,允许把参数替换到⽂本中,这种实现通常称为宏(macro)或定义宏 (define macro)。

下⾯是宏的申明⽅式:

 #define name( parament-list ) stuff

举例:

#define SOAURE(X) X*X

使用:

#define SOAURE(X) X*X
int main()
{int a = 5;printf("%d\n",SQUARE(a));return 0;
}
 预编译前后对比:

 结果:

 注意事项:

1.参数列表的左括号必须与name紧邻,如果两者之间有任何空白存在,参数列表就会被解释为stuff的一部分。

举例:
正确的:
#define SQUARE(X) X*X
错误的:
#define SQUARE (X) X*X

错误在于SQUARE举例(x)之间有一个空格,正常来说是不因该又间隔的,这二者应该紧贴在一起,也就是换在原型上来说,name应该和 ( parament-list )紧贴着!

2.不够严谨的写法导致的失误:

举例:
#define SOAURE(X) X*X
int main()
{int a = 5;printf("%d\n",SQUARE(a+2));return 0;
}

按照我们的想法因,再进行#define替换后,应该是(a+2)*(a+2),因为a=5,所以最后的结果因该是7*7=49,但是结果并不是如此。

结果:

使用预编译进行查看替换的情况:

 

并不是我们想象中的 (a+2)*(a+2),而是a+2*a+2,也就是5+2*5+2=5+10+2=17

所以严谨的写法应该是:
#define SQUARE (X) ((X)*(X))

 以此避免因为不严谨而带来的错误。

带有副作用的宏:

当宏参数在宏的定义中出现超过一次的时候,如果参数带有副作用,那么你在使用这个宏的时候就可能出现危险导致不可预测的后果。

副作用就是表达式求值的时候出现的永久性效果。 

 举例:

#define MAX(a, b) ((a)>(b)?(a):(b))

 当我们使用a++和b++这种带有永久性的效果时:

int main()
{int a = 15;int b = 9;int m = MAX(a++, b++);printf("%d\n",m);printf("a=%d b=%d\n",a,,b);return 0;
}

 预编译前后对比:

结果:

 

分析:

通过宏的替换,将   int m = MAX(a++, b++);替换为了int m = ((a++)>(b++)?(a++):(b++));

也正是因为替换,导致了++的不确定性。

  1. 1.因为a=15,再(a++)>(b++)中进行了使用,使用完后 a和b都因为++加上了1
  2. 2.因为再(a++)>(b++)中a比b大,所以执行?(a++):(b++));因为是a大,所以只执行(a++),所以最后答案输出给m的是16,但是输出完后,进行++执行,所以a又继续+1,得到17

宏的替换规则:

通过上诉我们得知了,宏是先把对应的内容替换掉,再进行运算。

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

  1. 在调⽤宏时,⾸先对参数进⾏检查,看看是否包含任何由#define定义的符号。如果是,它们⾸先 被替换。
  2. 替换⽂本随后被插⼊到程序中原来⽂本的位置。对于宏,参数名被他们的值所替换。  
  3. 最后,再次对结果⽂件进⾏扫描,看看它是否包含任何由#define定义的符号。如果是,就重复上 述处理过程。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Lua表公共操作

--表的公共操作 t1 {{age 1,name "123"},{age 2,name "456"}} t2 {name "Holens" , sex true} --插入 print(#t1) table.insert(t1,t2) print(#t1) print(t1[3].sex) print("*************************************")--删除 -…

wordpress插件-免费的wordpress全套插件

在当今数字化时代,网站和博客已经成为信息传递、观点分享和商业交流的重要平台。在这个背景下,WordPress作为最受欢迎的内容管理系统之一,无疑扮演着至关重要的角色。然而,要保持一个成功的WordPress网站,不仅需要出色…

关于操作系统与内核科普

关于操作系统与内核科普 一.什么是操作系统 操作系统是管理计算机硬件与软件资源的计算机程序。它为计算机硬件和软件提供了一种中间层。 操作系统是一种软件,主要目的有三种: 一.管理计算机资源,这些资源包括CPU,内存&#xff0…

【算法分析与设计】动态规划(下)

目录 一、最长公共子序列1.1 最长公共子序列的结构1.2 子问题的递归结构1.3 计算最优值1.4 举例说明1.5 算法的改进 二、最大子段和2.1 代码2.2 最大子段和问题的分治算法2.3 代码2.4 分治算法的时间复杂度2.5 最大子段和问题的动态规划算法 三、凸多边形最优三角剖分3.1 三角剖…

uniapp iOS离线打包——如何创建App并提交版本审核?

uniapp 如何创建App,并提交版本审核? 文章目录 uniapp 如何创建App,并提交版本审核?登录 appstoreconnect创建AppiOS 预览和截屏应用功能描述技术支持App 审核信息 App 信息内容版权年龄分级 价格与销售范围App 隐私提交审核 登录…

微信公众号网页授权登录获取用户基本信息

概述 微信公众号网页授权登录后微信获取用户基本信息,部署即可运行完整demo 详细 一、前言 (1)适合人群 1,JAVA服务端开发人员 2,初级人员开发人员 3,了解spring springboot maven 3,了…

共享办公室行业当前发展现状和未来发展前景

共享办公室行业是近年来迅速发展并受到广泛关注的一种办公模式。它为个人和企业提供了灵活、高效且经济实惠的办公环境。在过去的几年里,共享办公室行业经历了飞速增长并发生了巨大的变革,已经成为全球商业地产市场不可或缺的一部分。然而,共…

ORACLE 内存结构之系统全局区(SGA)

每个 Oracle 数据库实例都会在内存中分配一个很大的内存结构, 称为系统全局区(System Global Area), 这是一个大型的共享内存结构,每个Oracle进程都会访问它。 在Linux/Unix操作系统上,SGA是一个物理实体,使用操作系统命令能“看到它”。 它被操作系…

【C++11】多线程

多线程创建线程thread提供的成员函数获取线程id的方式线程函数参数的问题线程join场景和detach 互斥量库(mutex)mutexrecursive_mutexlock_guard 和 unique_lock 原子性操作库(atomic)条件变量库(condition_varuable&a…

Python 基于 Yolov8 + CPU 实现物体检测

目录 一、开发环境 二、安装 Python 基于 Yolov8 物体检测关联库 2.1 打开命令提示符(cmd)或终端,安装库 2.2 关联库安装过程遇到的问题 三、基于 Yolov8 物体检测代码实现(完整) 3.1 Yolov8 物体检测完整代码…

(二)Python编程环境搭建

本章重点介绍 Python 编程环境的搭建,包括各个平台下 Python 的下载和安装,常见 IDE 的使用,如何运行 Python 程序等。还会亲自带着大家编写并运行第一个 Python 程序,让大家认识一下最简单的 Python 代码。 本章的后半部分还介绍…

web:[ACTF2020 新生赛]Upload

题目 点进页面&#xff0c;是一个文件上传&#xff0c;能联想到getshell 先尝试随便上传一个文件试试 显示上传的文件以jpg、png、gif结尾的图片 构造一句话木马&#xff0c;再将文件后缀改为jpg <?php eval($_POST[1234]);?> 显示上传成功&#xff0c;但是显示无法…