关于宏定义

一、#if 后面的表达式:

#define VERSION  2

#if defined x || y || VERSION < 3

1 .  首先处理defined运算符,defined运算符一般用作表达式中的一部分,如果单独使用,#if

defined x相当于#ifdef x ,而#if !defined x相当于#ifndef x。在这个例子中,如果x 这个

宏有定义,则把definedx替换为1 ,否则替换为0 ,因此变成#if 0 || y || VERSION < 3。

2 .  然后把有定义的宏展开,变成#if 0 || y || 2 < 3 。

3 .  把没有定义的宏替换成0 ,变成#if 0 || 0|| 2 < 3 ,注意,即使前面定义了一个变量名

是y ,在这一步也还是替换成0 ,因为#if 的表达式必须在编译时求值,其中包含的名字只能是

宏定义。

4 .  把得到的表达式0 || 0 || 2 < 3像C 表达式一样求值,求值的结果是#if 1,因此条件成立

 

assert 是头文件assert.h 中的一个宏定义,执行到assert(is_sorted())这句时,如

果is_sorted() 返回值为真,则当什么事都没发生过,继续往下执行,如果is_sorted()返回值为假

(例如把数组的排列顺序改一改),则报错退出程序:

main: main.c:33: binarysearch: Assertion`is_sorted()' failed.

Aborted

在代码中适当的地方使用断言(Assertion)可以有效地帮助我们测试程序。也许有人会问:我们用

几个测试函数来测试binarysearch,那么这几个测试函数又用什么来测试呢?在实际工作中我们要

测试的代码绝不会像binarysearch这么简单,而我们编写的测试函数往往都很简单,比较容易保证

正确性,也就是用简单的、不容易出错的代码去测试复杂的、容易出错的代码。

测试代码只在开发和调试时有用,如果正式发布(Release)的软件也要运行这些测试代码就会严

重影响性能了,如果在包含assert.h之前定义一个NDEBUG 宏(表示No Debug),就可以禁

用assert.h 中的assert 宏定义,这样代码中的所有assert 测试都不起作用了:

#define NDEBUG

#include <stdio.h>

#include <assert.h>

...

注意NDEBUG 和我们以前使用的宏定义有点不同,例如#define N 20将N 定义为20,在预处理时把代

码中所有的标识符N 替换成20,而#define NDEBUG把NDEBUG 定义为空,在预处理时把代码中所有的

标识符NDEBUG 替换成空。这样的宏定义主要是为了用#ifdef 等预处理指示测试它定义过没有,而不

是为了做替换,所以定义成什么值都无所谓,一般定义成空就足够了。

还有另一种办法,不必修改源文件,在编译命令行加上选项-DNDEBUG 就相当于在源文件开头定义

了NDEBUG 宏。宏定义和预处理到第 21  章预处理再详细解释,在第 4 节 “ 其它预处理特性” 将给

出assert.h 一种实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值