Cherno C++ P55 宏

這篇文章我們講一下C++當中的宏。其實接觸過大型項目的朋友可能都被詭異的宏折磨過。

宏是在預處理當中,通過文本替換的方式來實現一些操作,這樣可以不用反復的輸入代碼,幫助我們實現自動化。至于預處理的過程,其實就是文本編輯,這個在之前的文章中有提到過。

替換的具體內容,可能是普通文本,也可以是參數變量等各種東西,可以說,就沒有什么是不能夠被宏替換掉的,我們可以拿來替換非常復雜的內容。但是需要注意的是,我們不希望拿宏來替換太多與C++特性有關的代碼,這樣并不是一個好的做法,因為會降低代碼的可讀性,雖然這樣做是沒有任何問題的。

舉個例子,我們用宏替換到我們常用的cin.get()語句:

#include<iostream>
#include<string>
#define WAIT std::cin.get()int main() {std::cout << "Hello World!" << std::endl;WAIT;
}

這樣寫當然是可以的,是能夠編譯通過的,但是這種寫法是很傻的。因為cin.get()是非常常用的語句,但是使用一個WAIT來替換它,反而會降低代碼的可讀性,讓其他人看得一頭霧水。

當然,分號也可以是宏的一部分,如果想的話也可以把分號寫在宏里面,那么就不用在代碼里面再寫分號了。

接下來我們看看如何在宏當中定義函數。

#include<iostream>
#include<string>
#define LOG(x) std::cout<< x << std::endl;int main() {LOG("Hello World!")std::cin.get();
}

我們運行代碼就會發現,我們正常的完成了打印,所以和實際寫cout效果是一樣的。

那么我們可以如何用宏幫助我們?一個有趣的實例就是在我們的日志類當中,我們希望在debug狀態下打印出我們需要的信息,但是在release版本當中不希望那么多東西都被打印到控制臺上,那么如何能夠區分debug還是release?在不同模式下函數應該是什么樣子的?這些我們就都可以用到宏來進行控制。

首先我們需要打開屬性,然后找到預處理界面,然后分別為debug和release兩個配置添加不同的宏,如圖所示:

我們在debug和release模式下分別定義PR_DEBUG和PR_RELEASE兩個宏,這樣我們就有了區分debug和release兩個模式的工具。然后我們就可以通過宏來控制我們是否需要打印:

#ifdef PR_DEBUG
#define LOG(x) //這里填寫我們需要的函數定義
#else
#define LOG(x)
#endif

如上述代碼所示,我們可以在debug模式下讓LOG函數真的為我們輸出一些東西,但是在release模式下,LOG就不代表任何代碼了,也就是說切換到release時,LOG處都會變成空白,宏自動的為我們刪除了在release時需要被刪除的代碼,這一點是非常nice的。

但是這樣使用也是有一點問題的,因為有的時候我們不想使用某個宏了,那我們還得去刪除,就很麻煩,最好的情況是給宏賦一個值,然后我們不想使用宏的時候,可以直接修改這個宏的值,那么這個宏就被禁用了。首先我們在設置當中為我們的宏賦值:

如圖所示,我們把PR_DEBUG賦值為1,然后我們在代碼當中可以直接這樣寫:

#if PR_DEBUG == 1

來判斷是不是在debug模式下。如果我們想要禁用這個宏,只需要

#define PR_DEBUG 0

就可以禁用這個宏了。

除此之外,我們還可以用宏來禁用一整塊代碼,如下所示:

#if 0LOG("Hello World!")
#endif

這樣中間部分代碼就都無效了。

如果我們想要代替多行代碼,可以用反斜線 \ 來替代,反斜線就是分行的轉義。

宏最常用的地方就是用來幫助我們debug,還可以自動查錯,也可以幫助跟蹤內存的使用情況。但是如果濫用宏,確實會導致代碼可讀性大幅降低,所以我們還是要慎重使用宏。以上就是本文的全部內容了,希望大家喜歡!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/70100.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/70100.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/70100.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

web第三次作業

彈窗案例 1.首頁代碼 <!DOCTYPE html><html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>綜合案例</title><st…

深入解析LVS命令參數及DR模式下的ARP抑制原理

深入解析LVS命令參數及DR模式下的ARP抑制原理 一、LVS簡介 Linux Virtual Server (LVS) 是基于Linux內核的高性能負載均衡解決方案&#xff0c;支持NAT、DR&#xff08;Direct Routing&#xff09;和TUN&#xff08;IP Tunneling&#xff09;三種模式。其中&#xff0c;ipvsad…

阿里云一鍵部署DeepSeek-V3、DeepSeek-R1模型

目錄 支持的模型列表 模型部署 模型調用 WebUI使用 在線調試 API調用 關于成本 FAQ 點擊部署后服務長時間等待 服務部署成功后&#xff0c;調用API返回404 請求太長導致EAS網關超時 部署完成后&#xff0c;如何在EAS的在線調試頁面調試 模型部署之后沒有“聯網搜索…

Win10環境借助DockerDesktop部署大數據時序數據庫Apache Druid

Win10環境借助DockerDesktop部署最新版大數據時序數據庫Apache Druid32.0.0 前言 大數據分析中&#xff0c;有一種常見的場景&#xff0c;那就是時序數據&#xff0c;簡言之&#xff0c;數據一旦產生絕對不會修改&#xff0c;隨著時間流逝&#xff0c;每個時間點都會有個新的…

【第13章:自監督學習與少樣本學習—13.1 自監督學習最新進展與實現方法】

凌晨三點的實驗室,博士生小王盯著屏幕里正在"自娛自樂"的神經網絡——這個沒有吃過一張標注圖片的模型,正在通過旋轉、拼圖、填色等游戲任務,悄悄掌握著理解世界的秘訣。這種魔法般的修煉方式,正是當今AI領域最炙手可熱的技術:自監督學習。 一、打破數據枷鎖:自…

數據庫報錯1045-Access denied for user ‘root‘@‘localhost‘ (using password: YES)解決方式

MySQL 報錯 1045 表示用戶root從localhost連接時被拒絕訪問&#xff0c;通常是因為密碼錯誤、權限問題或配置問題。以下是解決該問題的常見方法&#xff1a; 方法一&#xff1a;檢查用戶名和密碼 ? 確認用戶名和密碼是否正確&#xff1a; 確保輸入的用戶名和密碼完全正確&am…

八大排序——簡單選擇排序

目錄 1.1基本操作&#xff1a; 1.2動態圖&#xff1a; 1.3代碼&#xff1a; 代碼解釋 1. main 方法 2. selectSort 方法 示例運行過程 初始數組 每輪排序后的數組 最終排序結果 代碼總結 1.1基本操作&#xff1a; 選擇排序&#xff08;select sorting&#xff09;也…

與傳統光伏相比 城電科技的光伏太陽花有什么優勢?

相比于傳統光伏&#xff0c;城電科技的光伏太陽花有以下優勢&#xff1a; 一、發電效率方面 智能追蹤技術&#xff1a;光伏太陽花通過內置的智能追蹤系統&#xff0c;采用全球定位跟蹤算法&#xff0c;能夠實時調整花瓣&#xff08;即光伏板&#xff09;的角度&#xff0c;確…

FPGA的星辰大海

編者按 時下風頭正盛的DeepSeek,正值喜好宏大敘事的米國大統領二次上崗就業,OpenAI、軟銀、甲骨文等宣布投資高達5000億美元“星際之門”之際,對比尤為強烈。 某種程度上,,是低成本創新理念的直接落地。 包括來自開源社區的諸多贊譽是,并非體現技術有多“超越”,而是…

Elasticsearch:15 年來致力于索引一切,找到重要內容

作者&#xff1a;來自 Elastic Shay Banon 及 Philipp Krenn Elasticsearch 剛剛 15 歲了&#xff01;回顧過去 15 年的索引和搜索&#xff0c;并展望未來 15 年的相關內容。 Elasticsearch 剛剛成立 15 周年。一切始于 2010 年 2 月的一篇公告博客文章&#xff08;帶有標志性的…

嵌入式軟件、系統、RTOS(高軟23)

系列文章目錄 4.2嵌入式軟件、系統、RTOS 文章目錄 系列文章目錄前言一、嵌入式軟件二、嵌入式系統三、嵌入式系統分類四、真題總結 前言 本節講明嵌入式相關知識&#xff0c;包括軟件、系統。 一、嵌入式軟件 二、嵌入式系統 三、嵌入式系統分類 四、真題 總結 就是高軟筆記…

數據結構 day02

3. 線性表 3.1. 順序表 3.1.3. 順序表編程實現 操作&#xff1a;增刪改查 .h 文件 #ifndef __SEQLIST_H__ #define __SEQLIST_H__ #define N 10 typedef struct seqlist {int data[N];int last; //代表數組中最后一個有效元素的下標 } seqlist_t;//1.創建一個空的順序表 seq…

數據恢復-01-機械硬盤的物理與邏輯結構

磁盤存儲原理 磁盤存儲數據的原理&#xff1a; 磁盤存儲數據的原理是利用磁性材料在磁場作用下的磁化性質&#xff0c;通過在磁盤表面上劃分成許多小區域&#xff0c;根據不同的磁化方向來表示0和1的二進制數據&#xff0c;通過讀寫磁頭在磁盤上的移動&#xff0c;可以實現數據…

wordpress get_footer();與wp_footer();的區別的關系

在WordPress中&#xff0c;get_footer() 和 wp_footer() 是兩個不同的函數&#xff0c;它們在主題開發中扮演著不同的角色&#xff0c;但都與頁面的“頁腳”部分有關。以下是它們的區別和關系&#xff1a; 1. get_footer() get_footer() 是一個用于加載頁腳模板的函數。它的主…

DeepSeek 通過 API 對接第三方客戶端 告別“服務器繁忙”

本文首發于只抄博客&#xff0c;歡迎點擊原文鏈接了解更多內容。 前言 上一期分享了如何在本地部署 DeepSeek R1 模型&#xff0c;但通過命令行運行的本地模型&#xff0c;問答的交互也要使用命令行&#xff0c;體驗并不是很好。這期分享幾個第三方客戶端&#xff0c;涵蓋了桌…

跟著李沐老師學習深度學習(十一)

經典的卷積神經網絡 在本次筆記中主要介紹一些經典的卷積神經網絡模型&#xff0c;主要包含以下&#xff1a; LeNet&#xff1a;最早發布的卷積神經網絡之一&#xff0c;目的是識別圖像中的手寫數字&#xff1b;AlexNet&#xff1a; 是第一個在大規模視覺競賽中擊敗傳統計算機…

使用JavaScript實現深淺拷貝

1. 拷貝的基本概念和必要性 在 JavaScript 中&#xff0c;數據類型分為基本數據類型&#xff08;如 Number、String、Boolean、Null、Undefined、Symbol&#xff09;和引用數據類型&#xff08;如 Object、Array&#xff09;。基本數據類型存儲的是值本身&#xff0c;而引用數…

解析瀏覽器中JavaScript與Native交互原理:以WebGPU為例

引言 隨著Web應用復雜度的提升&#xff0c;開發者對瀏覽器訪問本地硬件能力的需求日益增長。然而&#xff0c;瀏覽器必須在開放性與安全性之間找到平衡——既不能放任JavaScript&#xff08;JS&#xff09;隨意操作系統資源&#xff0c;又要為高性能計算、圖形渲染等場景提供支…

T-Sql 打印所有用戶表的建表腳本

-- 聲明一個變量用于存儲表名 DECLARE TableName NVARCHAR(128); -- 聲明一個游標&#xff0c;用于遍歷所有用戶表 DECLARE TableCursor CURSOR FOR SELECT name FROM sys.tables WHERE type U; -- 打開游標 OPEN TableCursor; -- 從游標中獲取第一行數據 FETCH NEXT FROM Ta…

25/2/16 <算法筆記> MiDas原理

MiDaS&#xff08;Monocular Depth Sensing&#xff09;是一種基于單目深度估計的技術&#xff0c;它通過深度學習方法使用單張RGB圖像&#xff08;普通2D圖像&#xff09;來估算場景的深度圖&#xff08;Depth Map&#xff09;。相比于傳統的依賴專用深度傳感器&#xff08;如…