网站建设图库,私人订制网站推荐,贵州健康码app下载,东子WordPress目录
#x1f514;前言
#x1f514;#define 定义宏#xff08;无参#xff09;
#x1f514;#define 定义宏函数
#x1f514;宏的更多规则特性
#x1f514;宏的缺点
#x1f514;常见预处理指令 #x1f514;前言
C语言中源代码到可执行文件的第一阶段…
目录
前言
#define 定义宏无参
#define 定义宏函数
宏的更多规则特性
宏的缺点
常见预处理指令 前言
C语言中源代码到可执行文件的第一阶段也就是预处理阶段会检查源文件中的预处理指令语句和宏定义并对源代码进行相应的替换预处理过程还会删除程序中的注释和多余的空白符号。
预处理指令是以#开头的代码行#必须是该行除了空白符外的第一个字符#后是指令关键字在#和指令关键字之间允许存在若干个空白字符define是宏定义命令。在C语言程序中允许用一个标识符来表示一个字符串称为“宏”“宏”又分为有参和无参有参又称为“宏函数”被定义为“宏”的标识符称为“宏名”。
#define 定义宏无参
语法规定:#define name stuff
name标识符名\宏名
stuff可以是关键字、常量、关键字、标识符、标点符号、运算符表达式 在预处理阶段编译器会在程序中使用#define定义的标识符替换成stuff可以通过预处理生成的.i文件查看效果。 //stuff是数值常量
#define NUM 10 stuff是关键字
#define reg register //stuff是标点符号
#define GREATER_THAN //stuff的更多表达方式
#define do_forever for(;;)
//若定义的stuff过长可以分成几行写除了最后一行外每行的后面都加一个\(续行符
#define DBBUG_PRINT printf(file:%s\tline:%d\t \date:%s\ttime:%s\n,\__FILE__,__LINE__,\__DATE__,__TIME__)总结#define定义的name宏名在预编译阶段会将所有的宏名替换成stuffstuff内容被替换到源代码中。称为“宏代换”或“宏展开”。 注意define定义的标识符的时候后面加上“;”会将“;”认为是stuff中的内容。 #define 定义宏函数
宏函数的申明方式#define name(parament-list) stuff
parament-list:参数列表注意参数列表的左括号必须与name紧邻如果两者之间有空白存在参数列表就会被解释为stuff的部分。 宏函数存在的问题1
#include stdio.h#define SQUARE(x) x*x//定义一个宏函数求平方int main()
{int x SQUARE(31);//替换后x的计算结果是多少答案是7} 为什么呢 在给宏函数传参时如果传递的是一个表达式不会先计算表达式的结果再进行传参而是直接将表达式整体作为参数传递。 那么如何防止发生这样的情况呢 宏函数存在的问题2
#include stdio.h#define SUM(x,y) (x)(y)int main()
{int a 10;int b 5;int c SUM(a,b)*2;//替换后c的结果为20whyreturn 0;}
我们看看替换后的结果 这又该如何解决呢 总结在对数值表达式进行求值的宏定义应该用这两种方式加上括号避免在使用宏参数的操作符或邻近操作符之间不可预料的相互作用。 #define替换规则 1.在使用宏函数时首先对参数进行检查看看参数中是否包含任何#define定义的标识符如果有他们首先被替换。 2.替换的内容被插入到源文件原来的位置。对于宏函数参数名被他们的值替换 宏的更多规则特性
1.宏名一般用大写
2.使用宏可提高程序的通用性和易读性便于修改。
3.宏定义末尾不加分号
4.宏定义写在函数的大括号外面作用域为其后的程序通常放在开头
5.宏函数不可递归
6.宏定义不分配内存变量定义分配内存
7.字符串 中永远不包含宏
8.宏定义不存在类型问题他的参数也没有类型
宏的缺点
1.宏不能调试
2.宏由于与类型无关不够严谨
3.宏可能带来运算符优先级的问题导致容易出错
常见预处理指令
✨#define:宏定义
✨#undef:撤销已经定义过的宏名
✨#include:将另一个源文件嵌入到#include源文件中
✨#if~#endif:如果#if后面的常量表达式为真则编译#if~#endif之间的代码如果为假跳过这些代码不编译。
✨#if~#elif~#else~#endif:和if~else if~else类似可以建立更分支。
✨#ifdef symbol~endif:判断是否被定义定义了编译他们之间内容
✨#ifndef symbol~endif:判断是否被定义没定义编译他们之间的内容
✨#line:改变当前行数和文件名称是在编译程序中预先定义的标识符命令的基本形式#line number[filename]
✨#error:编译程序时只要遇到#error就会生成一个编译错误的提示信息并停止编译。
✨#pragma: 可以设定编译程序完成一些特点的动作可以通过编译程序的菜单中设置可以向编译程序传送各种指令。