網站首頁 編程語言 正文
C 預處理器
C 預處理器不是編譯器的組成部分,但是它是編譯過程中一個單獨的步驟。簡言之,C 預處理器只不過是一個文本替換工具而已,它們會指示編譯器在實際編譯之前完成所需的預處理。
指令 | 描述 |
---|---|
#define |
定義宏 |
#include |
包含一個源代碼文件 |
#undef |
取消已定義的宏 |
#ifdef |
如果宏已經定義,則返回真 |
#ifndef |
如果宏沒有定義,則返回真 |
#if |
如果給定條件為真,則編譯下面代碼 |
#else |
#if 的替代方案 |
#elif |
如果前面的 #if 給定條件不為真,當前條件為真,則編譯下面代碼 |
#endif |
結束一個 #if……#else 條件編譯塊 |
#error |
當遇到標準錯誤時,輸出錯誤消息 |
#pragma |
使用標準化方法,向編譯器發布特殊的命令到編譯器中 |
1.取消已定義宏
demo.h文件代碼如下
#ifndef __DEMO_H_ #define __DEMO_H_ #define PAI 3.14 #endif // __DEMO_H_
#include <stdio.h> #include "demo.h" /* 在 #include 與 main 函數中間區域使用#undef來取消以定義的宏,然后重新定義宏 */ #undef PAI #define PAI 33.14 int main() { printf("PAI = %G\n", PAI); } /* 輸出結果 PAI = 33.14 */
2.使用#ifdef來調試
#ifdef DEBUG /* 你的調試代碼 */ #endif // DEBUG
如果定義了 DEBUG,則執行處理語句。在編譯時,如果您向 gcc 編譯器傳遞了 -DDEBUG 開關量,這個指令就非常有用。它定義了 DEBUG,您可以在編譯期間隨時開啟或關閉調試。
常用預定義宏
宏 | 描述 |
---|---|
__DATE__ |
當前日期,一個以 “MMM DD YYYY” 格式表示的字符常量。 |
__TIME__ |
當前時間,一個以 “HH:MM:SS” 格式表示的字符常量。 |
__FILE__ |
這會包含當前文件名,一個字符串常量。 |
__LINE__ |
這會包含當前行號,一個十進制常量。 |
預處理器運算符?
1.宏延續運算符
\
一個宏通常寫在一個單行上。但是如果宏太長,一個單行容納不下,則使用宏延續運算符\
#include <stdio.h> #define PAI \ 3.1415926 int main() { printf("%.8f\n", PAI); }
2.字符串常量化運算符#
在宏定義中,當需要把一個宏的參數轉換為字符串常量時,則使用字符串常量化運算符#
。在宏中使用的該運算符有一個特定的參數或參數列表。就是把宏的參數變成字符串。
#include <stdio.h> #define PAI 3.1415926 //字符串常量化 #define CONVERT_TO_STR1(arg) "字符串常量化:" #arg //字符串常量化 #define CONVERT_TO_STR2(arg) CONVERT_TO_STR1(arg) int main() { printf("%s\n", CONVERT_TO_STR1(ABC)); printf("%s\n", CONVERT_TO_STR1(PAI)); printf("%s\n", CONVERT_TO_STR2(PAI)); } /* 輸出結果 字符串常量化:ABC 字符串常量化:PAI 字符串常量化:3.1415926 */
這里有幾點需要提一下。
1.宏定義中,當有多個字符串需要連接時,以空格來隔開每一個字符串即可。
2.當需要把一個宏字符串常量化時,需要按照先定義一個宏函數1,然后再定義一個宏函數2,然后宏函數2調用宏函數1即可,例如CONVERT_TO_STR2
調用CONVERT_TO_STR1
3.標記粘貼運算符##
宏定義內的標記粘貼運算符(##)會合并兩個參數。它允許在宏定義中兩個獨立的標記被合并為一個標記。
#include <stdio.h> #define PRINTF1(arg) printf("var" #arg " = %d\n" , var##arg) int main() { int var1 = 20; PRINTF1(1); }
/*
輸出結果
var1 ?= 20
*/
參數化的宏
使用注意點
用宏定義時,含參數時,參數本身要加(),此外,對參數的操作整體也要加()。
#define MAX(a,b) ((a)>(b)?(a):(b))
使用宏函數的時候不要使用++
/--
運算符
#include <stdio.h> #define MIN(A,B) ((A)<(B)?(A):(B)) int main() { char *p="ghi"; char a; a=MIN(*p++,'f');//不要使用自增/自減運算符 printf("%c\n",a); }
/*
輸出結果
f
*/
另,宏定義實現指定大小的交換:
#define SWAP(a, b, size) \ unsigned int __size = (size); \ char *__a = (a), *__b = (b); \ do \ { \ char __tmp = *__a; \ *__a++ = *__b; \ *__b++ = __tmp; \ } while (--__size > 0);
總結
原文鏈接:https://blog.csdn.net/qq_45607873/article/details/123762885
相關推薦
- 2022-06-22 Python?裝飾器常用的創建方式及源碼示例解析_python
- 2022-11-20 TS?中的類型推斷與放寬實例詳解_其它
- 2022-06-16 Python語法學習之正則表達式的使用詳解_python
- 2023-05-29 Python常見異常的處理方式淺析_python
- 2023-05-16 golang-gorm自動建表問題_Golang
- 2022-12-12 Android?WindowManager深層理解view繪制實現流程_Android
- 2022-07-13 解決 Webpack TypeError: cli.isMultipleCompiler is no
- 2022-09-05 用兩個隊列模擬一個棧
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支