網站首頁 編程語言 正文
1.條件編譯的時機
我們都知道vscode其實是一個編輯器,你要在上面跑C或者C++你需要配置編譯器,拿編譯器是怎樣吧一個文本文件變成一個可執行文件的呢?
那必然是經歷以下這四步
- 處理:宏替換,頭文件的展開,去注釋,條件編譯
- 編譯:將預處理后的源文件轉換為匯編語言文件,只編譯源文件,不編譯頭文件,頭文件在剛剛預處理階段已經展開。
- 匯編:雖然叫做匯編,但是不是轉變為匯編代碼,而是將剛剛的匯編語言文件轉換為機器碼,也就是二進制文件。
- 鏈接:將生成的二進制代碼與庫函數以及其他目標文件,通過鏈接器鏈接起來形成可執行文件的過程。
分析了以上過程由此可以很清晰的得出這個結論,條件編譯是在預處理的時候發生的。
2.條件編譯的作用
條件編譯是指預處理的時候根據條件編譯的指令有條件的選擇源程序中的一部分代碼送給編譯器進行編譯,進行有選擇性的操作,防止宏替換的內容重復包含。
常見的條件編譯指令如下:
常見條件編譯指令
3.#if #else #endif
#if 表達式
// code
#else
#endif
如果表達式為真則#if后程序段被調用
明顯發現第一段的色段跟第二段的色段都不一樣!肯定是第一句輸出了!
可以看到他直接call調用的就是標準命名空間下的operator類里面的函數,其實也就是 << 輸出
4.#ifndef #define #endif
#ifdef 標識符
#define 標識符 替換列表
// code
#endef
- 一般用于檢測程序中是否已經定義了名字為某標識符的宏,如果沒有定義該宏,則定義該宏,并選中從 #define 開始到 #endif 之間的程序段;
- 如果已定義,則不再重復定義該符號,且相應程序段不被選中。
我們都知道NULL在C中是一個宏,宏有時也會引起不必要的問題在C++11中則有了nullptr,所以這塊顯示是已經被宏過了,所有不執行#define 到#endef的程序段所以看起來是灰色的。
紅色框框是每個函數都有的,就是主函數棧幀開辟和銷毀的過程,再看中間好家伙啥都沒有,再次印證了,我們說的如果沒有定義該宏,則定義該宏,并選中從 #define 開始到 #endif 之間的程序段;如果已定義,則不再重復定義該符號,且相應程序段不被選中。
該條件編譯指令更重要的一個應用是防止頭文件重復包含。
如果 f.c 源文件中包含 f1.h 和 f2.h 兩個頭文件,而 f1.h 頭文件及 f2.h 頭文件中均包含 f3.h 頭文件,則 f.c 源文件因為包含了 f1.h 和 f2.h 兩個頭文件,所以中重復包含 f3.h 頭文件??刹捎脳l件編譯指令,來避免頭文件的重復包含問題。
#ifndef _HEADNAME_H_
#define _HEADNAME_H_
//頭文件內容
#endif
- 當該頭文件第一次被包含時,由于沒檢測到該頭文件名對應的宏名,則定義該頭文件名對應的宏,其值為該系統默認。并且,該條件編譯指令選中 #endif 之前的頭文件內容;
- 如果該頭文件再次被包含時,由于檢測到已存在以該頭文件名對應的宏名,則忽略該條件編譯指令之間的所有代碼,從而避免了重復包含。
5.#if #elif #else #endif
#if 條件表達式1
// code1
#elif 條件表達式2
//code 2
#else
//code 3
#endif
- 功能為:先判斷條件1的值,如果為真,則程序段 1 被選中編譯;
- 如果為假,而條件表達式 2 的值為真,則程序段 2 被選中編譯;
- 其他情況,程序段 3 被選中編譯。
6.#ifdef #endif
#ifdef 標識符
//code
#endif
- 如果檢測到已定義該標識符,則選擇執行相應程序段被選中編譯;
- 否則,該程序段會被忽略。
#include <iostream>
using namespace std;
#define PI 3.14
int main() {
#ifdef PI
#undef PI
cout << "PI 已經被取消宏" << endl;
#endif
}
如果檢測到符號 PI已定義,則刪除其定義,并選中相應的程序段。
原文鏈接:https://blog.csdn.net/qq_50119037/article/details/124336378
相關推薦
- 2022-07-14 Python中添加搜索路徑的方法實例_python
- 2022-06-23 Python基于鏈接表實現無向圖最短路徑搜索_python
- 2022-07-02 Python列表1~n輸出步長為3的分組實例_python
- 2022-08-12 Pandas中DataFrame常用操作指南_python
- 2022-06-18 C#多線程之線程中止Abort()方法_C#教程
- 2022-04-15 Android開發Jetpack組件Room用例講解_Android
- 2022-10-25 Python條件語句的使用_python
- 2022-08-04 python中可以發生異常自動重試庫retrying_python
- 最近更新
-
- 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同步修改后的遠程分支