C语言基础知识:#undef及其用法

目录

1、调试头文件

2、防止宏定义冲突

3、增强代码可读性

4、自定义接口


#undef 标识符是C语言中的一个重要的标识符,它的作用是用来将前面定义的宏标识符取消定义。 

它常用在以下情况:

1、调试头文件

#ifdef _DEBUG_
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#define new DEBUG_NEW
#endif
 
/*********** 例程6:debug.h ***********/

2、防止宏定义冲突

在一个程序块中用完宏定义后,为防止后面标识符冲突需要取消其宏定义。

#include <stdio.h>
 
int main()
{
#define MAX 200
printf("MAX = %d\n", MAX);
#undef MAX
 
    int MAX = 10;
    printf("MAX = %d\n", MAX);
 
    return 0;
}
 
/******** 例程1:main.c ********/

在一个程序段中使用完宏定义后立即将其取消,防止在后面程序段中用到同样的名字而产生冲突。

3、增强代码可读性

在同一个头文件中定义结构类型相似的对象,根据宏定义不同获取不同的对象,主要用于增强代码的可读性。

例如:在头文件student.h中定义两个学生对象(小明和小红),两个对象互不干涉。

#ifdef MING
#define MING_AGE 20
#define MING_HEIGHT 175
#endif
 
#ifdef HONG
#define HONG_AGE 19
#define HONG_HEIGHT 165
#endif
 
/******** 例程2:student.h ********/

在源文件中使用这两个对象:

#include <stdio.h>
 
#define MING
#include "student.h"
#undef MING
#define HONG
#include "student.h"
#undef HONG
 
int main()
{
printf("Xiao Ming's age is %d.\n", MING_AGE);
printf("Xiao Hong's age is %d.\n", HONG_AGE);
 
return 0;
}
 
/******** 例程3:main.c ********/

在一个头文件里定义的两个对象与分别在两个头文件里定义效果相同,但如果将相似的对象只用一个头文件申明,可以增强源代码的可读性。

4、自定义接口

将某个库函数包装成自定义接口,而只允许用户调用自定义接口,禁止直接调用库函数。

(此例来源于《C和指针》)

例如,自定义安全的内存分配器接口:

/*
** 定义一个不易发生错误的内存分配器
*/
#include <stdlib.h>
 
#define malloc                         //防止直接调用malloc!
#define MALLOC(num, type)   (type *)alloc((num) * sizeof(type))
extern void *alloc(size_t size);
 
/*********** 例程4:alloc.h ***********/

其中“#define malloc”是为了防止用户直接调用库函数malloc,只要包含了这个头文件alloc.h,就不能直接调用库函数malloc,而只能调用自定义函数MALLOC,如果用户要调用库函数malloc编译器会发生错误。

自定义安全的内存分配器的实现:

/*
** 不易发生错误的内存分配器的实现
*/
#include <stdio.h>
#include "alloc.h"
#undef malloc
 
void *alloc(size_t size)
{
    void *new_mem;
    new_mem = malloc(size);
    if(new_mem == NULL)
    {
        printf("Out of memory!\n");
        exit(1);
    }
    return new_mem;
}
 
/*********** 例程5:alloc.c ***********/

因为在实现中需要用到库函数malloc,所以需要用这一句“#undef malloc”取消alloc.h中对malloc的宏定义。

这种技巧还是比较有意思的,用于对已经存在的库函数进行封装。而且如果包含了自定义接口文件,就不能直接调用库函数,而只能调用自定义封装的函数。

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值