分享

【C语言更新】熟练使用#define宏定义,中文编程不是梦

 乐创客搬运工 2021-01-27

文/Edward


前面我们在讲解程序编译的时候,编译器做的第一步就是预处理。C语言的预处理,其实是编译器在对整个工程编译之前做的一些文本性质的工作,例如我们经常使用的#include,这就是一个典型的文件包含预处理,当启动编译的时候,编译器首先先做预处理,即将#include后面包含的那个文件里面的内容,全部复制到当前的.c文件中来,接着,再进行C语言源文件的编译。除了文件包含之外,C语言中的预处理还有很多,而这些预处理对于我们编程来说,都可以帮助我们提高代码的易读性和代码质量。


#define

#define预处理的作用,一般在一些书上面仅仅称其为“宏定义”,其实这个称呼是不严谨的,一个#define预处理其实包含两种意思,第一种意思是“宏定义”,第二个层面的意思是替换,下面的内容,我们将会以上面两层意思分开讲解。

  #define替换

也许我们在单片机编程中,绝大多数用户使用的仅仅只是#define预处理的替换功能,#define的替换格式为:

#define NAME 需要替换的内容

比如,我们一般常用的用来定义圆周率Π,就可以写成:

#define PI 3.1415926

那么以后的程序代码里面只要出现PI这个标号,编译器都将直接将其替换成一个浮点数3.1415926。

在用#define定义标号的时候需要注意,一般地我们都以大写字母来拼写这个标号,而且这个标号在用#define定义时,我们都默认地将其放入相应的.h头文件中。如图1所示的求圆形面积和周长的程序。

图1 求圆的周长和面积

用#define定义的标号不止可以替换一些数值,还可以替换关键词和函数,例如,想要让C语言变成一个中文的编程语言,就可以直接用#define定义中文标号来替换C语言的关键词,如图2所示。

图2 用中文编写C语言

需要注意的是,MinGW编译器自身不支持中文类型的变量,所以如果要尝试只能在Visualstudio软件中使用MSVC来尝试。

#define除了可以替换数值、关键词和函数之外,还可以用来替换程序语句,我们可以将需要执行的程序语句,利用#define重新定义成一个标号,如图3所示。

图3 #define替换程序语句

在图3中,我们利用#define定义了一个程序计算语句,这个标号在程序执行的时候就会自动被替换成后面的2*3运算语句去执行了。接着我们再来看一段代码。如8-1-4所示。

图4 错误的#define替换

按照我们正常的理解,图4中的程序理论上来说应该输出25才对,但是为什么结果却和我们想象的不一样呢?这是因为#define定义的标号在编译的时候是文本直接替换的,因此当在程序里面执行STENCE*STENCE的时候,我们认为的应该执行(2+3)*(2+3),而实际上STENCE是直接被2+3替换的,所以在程序编译时的真实替换应该是2+3*2+3,因此输出的值才和我们想象中的不一样,这就是典型的#define替换错误。只需要在2+3外面加上括号即可,如图5所示。

图5 正确的#define程序语句替换

而当我们在替换多条语句的时候,一定要用“do{……}while(0);“的形式来将标号里面的多条执行语句打包好,以防止不必要的错误产生。如图6所示。

图6# define替换多条程序语句

 

#define除了用作简单和复杂的程序文本替换之外,这个机制还包括了一个规定,即可以将参数替换到文本中去进行计算,这种实现通常被称为宏(macro)。

宏定义的声明方式为:

#define 宏名称(参数1,参数2,……)  带参数的表达式

当宏被调用时,参数列表中的每一个值都会与宏表达式实体中的每一个值所一一对应,并且进行替换。如,我们定义一个用于计算平方的宏,就可以写成:

#define SQUARE(x) x*x

下面程序使用宏定义计算5的平方,就可以直接使用SQUARE(5)

如图7所示,我们可以将圆的面积和周长计算分别写成宏的形式进行运算。

图7 宏定义计算圆的周长和面积

但是还需要注意的是,宏定义的参数替换也仅仅是文本形式的替换,如图8所示。

图8 宏定义的错误计算

图8的程序中,我们原本想的是,输入的半径变成11之后,通过调用宏,并且传入参数rad+ 1,理论上来说应该和8-1-7中输出一样的计算结果才对,但是实际上,这个传入的参数在替换时也是仅仅被当作文本去替换了,因此图8程序实际的计算过程应该是,以周长为例,2*3.1415926*11+1=70.12。所以在宏定义的时候,我们也应该为其参数增加括号,以提高整个宏的完整性。如图9所示。

图9 宏定义参数的正常使用

除了上述的功能之外,宏定义最常被使用的就是比较两个数的大小了,之前我们比较两个数的大小都是使用if来判断的,但是学了宏之后,结合三目运算符就可以直接使用一个宏定义来完成了,如图10所示。

图10 使用宏定义比较大小


本章历程代码已经上传Git,仓库地址:https:///huangqilong119/joy-create-clanguage-code.git




    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多