首页 理论教育 C++语言中的缩写与宏定义

C++语言中的缩写与宏定义

时间:2023-08-13 理论教育 版权反馈
【摘要】:如果要问最有技巧性的编译宏指令是哪一条的话,答案毫无疑问就是#define。但#define的某些作用仍然是简洁而不可替代的。先来看一下#define最基本的语法。现行的C++标准已经允许用const前缀而非#define来定义常量。可以看出,#define的这种用法看起来非常像是一个函数,其实现的功能也和函数非常相似。读者可以先尝试不使用#define编写该题的程序,然后再阅读下面使用#define简化程序编写的参考解答,以对#define可能起到的作用有更深刻的理解。

C++语言中的缩写与宏定义

如果要问最有技巧性的编译宏指令是哪一条的话,答案毫无疑问就是#define。尽管随着C++标准的发展,它的大部分功能正在逐渐被C++更清晰更有效的新语法所取代。但#define的某些作用仍然是简洁而不可替代的。

先来看一下#define最基本的语法。语法1:

功能1:

将该宏指令之后所有的标识符1替换为内容1。

来看一个例子——迭代法计算sqrt(2)。

例14-2

只需调节程序开头的ZERO定义即可调节整个运算过程的精度。对于更加复杂,会多次用到ZERO的问题,还能省去每次都要写若干“0”的麻烦并避免出现前后不一的错误

这种形式的#define主要用于定义一些重要或者可能经常变化的常量,以达到增加可读性、方便记忆和修改之类的功能,或者是用来实现“缩写”,是实际应用中最常见的用法。如果读者想看更加典型的例子,不妨参阅编译器附带的limits.h、.h等负责常量定义的头文件。现行的C++标准已经允许用const前缀而非#define来定义常量。前述例14-2中的:

用新语法来写就是:

新旧两种语法各有优势。const定义的常量拥有类型可以更好地融入编译流程(比如把它赋值给float的时候会有更友好的warning),而#define定义的常量可以兼容其他C“方言”,比如C99或Objective C,在与其他平台或其他人代码对接的时候经常用到。

作为最强大的编译宏指令,#define的功能还不止这些,来看一下#define的一个高级用法。

语法2:

功能2:

定义一个“宏”,将后面出现的标识符替换为内容,并将内容中的各“形参”对应替换为调用时给出的“值参”。

请看下面的例子。

例14-3 从键盘读入A、B两人的年龄,并输出其中的较大者。

在上面的程序中,MAX(a,b)会被预处理器按规则替换成(((a)>(b))?(a):(b))。从而达到了求出a、b中较大者的目的。

可以看出,#define的这种用法看起来非常像是一个函数,其实现的功能也和函数非常相似。但要注意,它的作用机理和函数是完全不同的,#define只是简单地将调用宏的位置替换成宏定义的内容,因此宏的参数除引号与小括号必须配对外,完全不受C语言语法的限制,只要能保证预处理器处理后的最终结果能通过编译,诸如单个的运算符、不配对的方括号,不完整的关键字之类的内容都可以出现在宏的参数中。最终宏的作用只和预处理器处理得到的结果有关,而与其本身的形式无关。

而函数和对函数的调用都是要通过编译器生成机器码的,因此自然写法上要受到C语言语法的诸多限制,但正因如此,编译器会保证函数最终发挥的作用(也就是生成的机器码)严格符合函数本身的描述。这个实现原理上的不同看似无关紧要,但忽略它可能会造成致命的问题,这一点会在14.2.3节中详细讲述。

宏定义中还有两种起特殊作用的符号。

(1)#x:参数x的字符串形式的内容。在同时输出算式和值的时候很方便。

例14-4

(www.xing528.com)

该程序会输出:

(2)a##b:将a和b连接。一般用于需要将参数和其他东西连接起来的场合。

例14-5

最后来看一个比较复杂的综合性例子。

例14-6 处理器模拟。

假想这样的一个8位处理器:内存有256字节,地址为0~255。

处理器内部有一个能容纳8个单字节元素的堆栈S和一个3bit的栈指针SP。为了描述方便,定义ST(i)为S[SP+i](即堆栈S中第SP+i个元素)。mem(i)为内存地址i处的一个字节。

处理器共有25条指令,见表14-1。

表14-1 处理器的25条指令

续表

所有运算溢出后均舍弃高位,例如SP=7时执行一条POP指令后SP会回到0;计算25∗12会得到44(也就是300&255)。除法为整除,且程序保证不会除0。

处理器从地址0开始执行指令。定义指令a的下一条指令为第一字节在指令a最后一字节下一字节的指令。如果不遇到特殊指令,处理器执行完一条指令后会继续执行该指令的下一条指令。

编程模拟这个处理器的运行。内存中的初始数据从文件“mem.in”输入。mem.in中包含256个2位十六进制整数,表示内存地址0~255的值。

这里提供一个测试用的mem.in:

这个假想CPU上的程序会依次完成下列事情:

(1)输出256以内的质数表。

(2)输入一个数x,然后输出一个高度为x的星号金字塔

(3)输出随机算式(两数加、减或乘)并要求用户输入答案,答对时会输出“^_^”,答对五次后程序结束。

读者可以先尝试不使用#define编写该题的程序,然后再阅读下面使用#define简化程序编写的参考解答,以对#define可能起到的作用有更深刻的理解。

参考解答:

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈