CAndPrimer_14

C和指针第十四章 预处理器 笔记

  • Dargon

  • 2020/11/01

  • 所遇到的的重要的问题

  • 教科书 来自:《C And Primer》第十四章

关于#define 宏的正确用法

  • 用一个例子来说明问题是如何出现的
#define SQUARE(x) x *x
SQUARE(5);

我们客观认为 处理的结果就是 5*5
但是,这存在着一个问题,当这样输入的时候

a =5;
printf("%d\n", SQUARE(a +1));

这段代码不会打印 36 而是11 出来
实际上这条语句被替换成了

printf("%d\n", a +1 *a +1);

这就很明显了,它没有按照我们预想的次序进行求值。

  • 当我在#define 宏定义中加上括号 就可以解决了
#define #define SQUARE(x) (x) *(x)
printf("%d\n", (a +1) *(a +1));

这样就解决了 这个问题,但是……

  • 我们定义下面这个
#define DOUBLE(x) (x) +(x)

定义中使用了括号 避免出现前面的问题,但是,

a =5;
printf("%d\n", 10 *DOUBLE(a));

Warning: 看上去实在打印10 *10 ,其实是在打印55 =10 *5 +5;

  • Conclusion
    我们在#define 宏(define macro) ,都应该类似下面的定义 ,加上一对 ()
#define DOUBLE(x) ( (x) + (x) )

加上一对 (),避免在使用 宏(macro) 时,由于参数中的操作符或邻近的操作符之间不可预料的相互作用。

关于#include 文件包含问题

  • 我们一般使用< > 去包含,库文件 (library filename)
  • 使用“ ”, 去包含自己写的/创建的文件
#ifndef _HEAD_H__
#define _HEAD_H__



/* 全局变量声明区 */
enum {
    RUN_TEST_OK =0,
    RUN_TEST_ERROR,
    RUN_TEST_SUSPEND
};


/* 库头文件声明区 */
#include <stdio.h>   /* NULL  */
#include <stdlib.h>  /* malloc(), free()  */
#include <string.h>
#include <assert.h>  /* assert() */
#include <errno.h>   /* errno, ERANGE */
#include <math.h>    /* HUGE_VAL */
#include <ctype.h>   /* "A" -> "a" */
#include <limits.h>
#include <stdarg.h>  /* var */
#include <float.h>
#include <stddef.h>  /* size_t */
#include <ctype.h>   /* describe error */

/* 自定义函数头文件声明区 */
#include "alloc.h"
#include "name.h"
#include "rearrange.h"
#include "braces.h"
#include "exercise_04.h"
#include "exercise_05.h"
#include "exercise_06.h"
#include "exercise_07.h"
#include "exercise_08.h"
#include "exercise_09.h"
#include "exercise_10.h"
#include "exercise_11.h"
#include "exercise_12.h"
#include "exercise_13.h"


#define MALLOC(num, type)  (type *)alloc( (num) * sizeof(type) )
extern void *alloc( size_t size );
#define DEBUG_PRINT ptintf("File %s line %d: x =%d, y =%d, z =%d", __FILE__, __LINE__,x, y, z)

#endif

应该有一个自己写的 head.h 文件,只用来包含 各种各样的 .h 文件,管理更方便,避免冗杂

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值