#undef的語法
定義:#undef 標識符,用來將前面定義的宏標識符取消定義。
整理了如下幾種#undef的常見用法。
1. 防止宏定義沖突
在一個程序塊中用完宏定義后,為防止后面標識符沖突需要取消其宏定義。
例如:
#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; }
在一個程序段中使用完宏定義后立即將其取消,防止在后面程序段中用到同樣的名字而產生沖突。
2.增加代碼可讀性
在同一個頭文件中定義結構類型相似的對象,根據宏定義不同獲取不同的對象,主要用於增強代碼的可讀性。
例如:在頭文件student.h中定義兩個學生對象(小明和小紅),兩個對象互不干涉。
#ifdef MING
#define MING_AGE 20
#define MING_HEIGHT 175
#endif
#ifdef HONG
#define HONG_AGE 19
#define HONG_HEIGHT 165
#endif
在源文件中使用這兩個對象:
#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. 自定義接口
將某個庫函數包裝成自定義接口,而只允許用戶調用自定義接口,禁止直接調用庫函數。
例如,自定義安全的內存分配器接口:
/* ** 定義一個不易發生錯誤的內存分配器 */ #include <stdlib.h> #define malloc //防止直接調用malloc! #define MALLOC(num, type) (type *)alloc((num) * sizeof(type)) extern void *alloc(size_t size);
其中“#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; }
因為在實現中需要用到庫函數malloc,所以需要用這一句“#undef malloc”取消alloc.h中對malloc的宏定義。
這種技巧還是比較有意思的,用於對已經存在的庫函數進行封裝。而且如果包含了自定義接口文件,就不能直接調用庫函數,而只能調用自定義封裝的函數。
4. 用於調試頭文件中
用於調試頭文件中,偶然看到這樣一個代碼用到了#undef,寫於此作為記錄:
#ifdef _DEBUG_ #undef THIS_FILE static char THIS_FILE[] = __FILE__; #define new DEBUG_NEW #endif