C++入門自學Day1-- C語言的宏函數和C++內聯函數

一、函數調用開銷

函數調用會涉及:

  • 參數壓棧(或寄存器傳參)

  • 跳轉到函數體

  • 返回值處理

  • 棧幀銷毀

這個過程對小函數來說可能非常浪費,因此,宏函數和內聯函數的目的就是避免“函數調用的開銷”,通過代碼展開(替換)來實現“零調用成本”。

?二、C語言的宏函數

1、 定義方式

宏函數使用?#define?宏定義語法:

#define SQUARE(x) ((x) * (x))

2、實現原理

  • 預處理器階段完成替換

  • 所有使用?SQUARE(x)?的地方,都會被文本替換為?((x)*(x))(簡單地字符串替換)

  • 不是函數調用,也沒有類型檢查

優點

  • 快!展開是直接替換,沒有函數調用的成本

  • 支持各種類型(無類型限制)

缺點

  • 不安全:可能造成副作用

SQUARE(i++) ?→ ((++i) * (++i)) ?// i 被加了兩次!

#define SQUARE(x) ((x)*(x))int main(){int i = 5;cout << "6*6 = " << SQUARE(++i);
}

輸出:

????????6*6 = 42 ??;因為++i加了兩次,所以是6*7;

????????調試困難:宏不是函數,沒法打斷點進去

????????沒有作用域控制:容易污染命名空間

?三、C++ 的內聯函數(inline function)

1、定義方式

inline int square(int x) {return x * x;
}

只是在常規的函數定義之前加個 “inline”。

2、實現原理

  • 編譯器在?編譯階段?判斷是否將調用處用函數體替代(不保證一定 inline,只是建議)

  • 真實函數、具有類型檢查、作用域、安全。

  • 利用空間換時間的原理 。

?優點

???????安全、類型檢查完整

  • 可以用調試器調試

  • 支持遞歸(編譯器可能不展開)

  • 支持模板和泛型

  • 可以與?constexpr、template?配合

?缺點

? ? ? ? 內聯函數不建議聲明和定義分離,分離會導致連接錯誤。因為inline被展開了,就沒有了函數地址,鏈接就找不到了。

  • 濫用內聯會導致代碼膨脹(code bloat),生成的可執行文件變大

  • 只適合小函數,復雜函數不一定 inline,(代碼小于二十行,遞歸)。

  • 編譯器有最終決定權,inline?是一種建議而非強制

四、對比總結表

特性

宏函數(C)

內聯函數(C++)

執行階段

預處理階段

編譯階段

類型檢查

? 無類型檢查

? 有完整類型檢查

安全性

? 易出錯,有副作用

? 安全,作用域清晰

調試性

? 不可調試

? 可調試

遞歸支持

? 不支持

? 支持(是否內聯由編譯器決定)

用法建議

僅限非常簡單的表達式

小函數、頻繁調用的函數

性能提升

?(暴力替換)

?(編譯器優化,智能展開)

五、【面試題】

1、宏的優缺點?

2、c++有哪些技術可以替代宏?

????????利用常量定義換用const。

#define N 10;

替換為

const int N = 10;

????????短小函數定義,換用內聯函數。

宏函數定義 -->利用內聯函數替換

#define MAX(a, b) ((a) > (b) ? (a) : (b))// 改寫為模板內聯函數
template <typename T>
inline T Max(T a, T b) {return a > b ? a : b;
}

3、?宏和內聯函數的本質區別是什么?

考點:?宏是預處理階段處理,內聯函數是編譯階段處理。

  • 宏在預處理階段展開,是文本替換,沒有類型檢查,也沒有作用域限制;

  • 內聯函數是真正的函數,有類型檢查,有作用域,并能調試。

4、?什么是內聯函數?什么時候應該使用?

考點:?減少函數調用開銷,提升性能。

  • 適合小函數,如 getters/setters;

  • 不建議用于遞歸、虛函數、復雜函數;

  • 編譯器可以不采納?inline?建議(非強制)。

5、內聯函數會影響編譯時間和可執行文件大小嗎?

考點:

  • 增加編譯時間(編譯器要展開多次);

  • 增加可執行文件大小(代碼膨脹);

  • 但可以減少函數調用棧的開銷。

好了本期有關于c語言宏定義知識回顧和c++內聯函數的分享就到這里結束了,謝謝大家的支持和點贊收藏👍。

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

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

相關文章

Pytorch混合精度訓練最佳實踐

混合精度訓練&#xff08;Mixed Precision Training&#xff09;是一種通過結合單精度&#xff08;FP32&#xff09;和半精度&#xff08;FP16/FP8&#xff09;計算來加速訓練、減少顯存占用的技術。它在保持模型精度的同時&#xff0c;通常能帶來 2-3 倍的訓練速度提升&#x…

Qt C++動態庫SDK在Visual Studio 2022使用(C++/C#版本)

01 將C SDK 集成到 IDE 中以下是在 Microsoft Visual Studio 平臺下 SDK 的集成。2.1 Visual Studio 平臺下 C/C環境配置及集成到 IDE 中xxx.lib 和 xxx.dll 適合在 Windows 操作系統平臺使用&#xff0c;這里以 VS2022 環境為例。2.1.1 C/C 工程環境配置與集成1、C# SDK 接口…

大語言模型 LLM 通過 Excel 知識庫 增強日志分析,根因分析能力的技術方案(2):LangChain + LlamaIndex 實現

文章大綱 1 技術原理總覽 2 詳細實現步驟(含代碼) 2.1 環境準備 2.2 Excel → LlamaIndex 節點 2.3 構建向量索引(FAISS 本地) 2.4 Google Cloud 向量檢索(可選替換 FAISS) 2.5 LangChain 問答鏈 A. RAG 模式(向量檢索 + LLM 生成) B. SQL 模式(無 RAG,直接查表) 2.…

提升ARM Cortex-M系統性能的關鍵技術:TCM技術解析與實戰指南

文章目錄引言一、TCM基礎架構與工作原理1.1 TCM的物理特性1.2 與緩存機制的對比1.3 ARM Cortex-M系列對TCM的支持二、TCM的典型應用場景2.1 實時中斷處理2.2 低功耗模式下的待機代碼2.3 高性能算法執行2.4 系統初始化階段的關鍵代碼三、實戰指南&#xff1a;在STM32H7上配置和優…

大數據之路:阿里巴巴大數據實踐——大數據領域建模綜述

為什么需要數據建模 核心痛點 數據冗余&#xff1a;不同業務重復存儲相同數據&#xff08;如用戶基礎信息&#xff09;&#xff0c;導致存儲成本激增。計算資源浪費&#xff1a;未經聚合的明細數據直接參與計算&#xff08;如全表掃描&#xff09;&#xff0c;消耗大量CPU/內存…

實戰演練1:實戰演練之命名實體識別

實戰演練1:實戰演練之命名實體識別 命名實體識別簡介 代碼 命名實體識別簡介 什么是命名實體識別任務 命名實體識別(Named Entity Recognition,簡稱NER)是指識別文本中具有特定意義的實體,主要包括人名、地名、機構名、專有名詞等。通常包括兩部分: (1)實體邊界識別。(2)確定…

數據結構基礎內容(第七篇:堆、哈夫曼樹)

# 堆 Heap 優先隊列(Priority Queue) 結構性:用 *數組* 表示的完全二叉樹; 有序性:任一結點的關鍵字是其子樹所有結點的最大值(或最小值) * “最大堆(MaxHeap)”,也稱“大頂堆”:最大值 * “最小堆(MinHeap)”,也稱“小頂堆” :最小值 主要操作有: ? MaxHeap Create( i…

CS231n-2017 Lecture7訓練神經網絡(二)筆記

本節主要是神經網絡的動態部分&#xff0c;也就是神經網絡學習參數和搜索最優超參數的過程梯度檢查&#xff1a;進行梯度檢查&#xff0c;就是簡單地把解析梯度與數值計算梯度進行比較&#xff0c;防止反向傳播的邏輯出錯&#xff0c;僅在調試過程中使用。有如下技巧 &#xff…

IntelliJ IDEA 中左上方未顯示項目根目錄問題

問題&#xff1a; 在IDEA中編寫代碼時&#xff0c;發現左上方只顯示項目的子模塊&#xff0c;未顯示根項目名稱。 如圖所示&#xff0c;未顯示子模塊的根項目&#xff1a;問題分析 頂層根目錄未被識別為項目根目錄&#xff0c;需要手動添加識別。 問題解決 進入File – Project…

OpenCV 圖像變換全解析:從鏡像翻轉到仿射變換的實踐指南

前言處理圖像時&#xff0c;翻轉、旋轉、平移等操作很常用。OpenCV 提供了簡單的方法實現這些變換&#xff0c;本文帶你快速學會用它做圖像翻轉和仿射變換。1 圖像翻轉(圖像鏡像旋轉)在OpenCV中&#xff0c;圖片的鏡像旋轉是以圖像的中心為原點進行鏡像翻轉的。cv2.flip(img,fl…

【運維】Linux運維命令記錄

重置root密碼使用命令重新設置一下root賬戶的密碼 passwd root根據提示設置一下密碼&#xff0c;然后使用sudo -i 時輸入密碼就可以切換到root賬戶了ssh登陸以后&#xff0c;要用sudo -i命令給用戶提權&#xff0c;提到超級管理員&#xff0c;然后輸入密碼才有用

PandasAI連接LLM進行智能數據分析

1. 引言 Pandas是一個數據分析開源組件庫&#xff0c;提供了高性能、易用的數據結構和數據分析工具。它的核心的功能是其DataFrame對象&#xff0c;這是一個帶有行和列標簽的二維表格數據結構&#xff0c;支持缺失數據處理、時間序列功能、靈活的數據輸入輸出方法、數據對齊和…

Spring之【Bean的生命周期】

目錄 1、生成BeanDefinition BeanDefinitionRegistry接口 DefaultListableBeanFactory實現類 2、合并BeanDefnition AbstractBeanFactory類 3、BeanFactoryPostProcessor的方法回調 AbstractApplicationContext類 PostProcessorRegistrationDelegate類 4、BeanPostPro…

搜狐新聞直播間適配HarmonyOs實現點贊動畫

01背景介紹隨著新聞客戶端鴻蒙單框架系統適配工作的推進&#xff0c;從原來的基礎功能到現在已經適配全功能的85%以上。與此同時&#xff0c;我們也在持續深入挖掘鴻蒙系統的特性&#xff0c;以提升整體應用的質量與用戶體驗。在這一過程中&#xff0c;動畫作為增強交互與視覺體…

83、設置有人DTU設備USR-M100采集傳感器數據,然后上傳阿里云服務

基本思想:設置M100 采集傳感器數據 一、首先將DTU設備USR-M100連接路由器上,然后使用python代碼搜索同一局域網設備, import platform import sys import os import time import threadinglive_ip = 0def get_os():os = platform.system()if os == "Windows":re…

P1019 [NOIP 2000 提高組] 單詞接龍

題目描述單詞接龍是一個與我們經常玩的成語接龍相類似的游戲&#xff0c;現在我們已知一組單詞&#xff0c;且給定一個開頭的字母&#xff0c;要求出以這個字母開頭的最長的“龍”&#xff08;每個單詞都最多在“龍”中出現兩次&#xff09;&#xff0c;在兩個單詞相連時&#…

詳解力扣高頻SQL50題之1633. 各賽事的用戶注冊率【簡單】

傳送門&#xff1a;1633. 各賽事的用戶注冊率 題目 用戶表&#xff1a; Users -------------------- | Column Name | Type | -------------------- | user_id | int | | user_name | varchar | -------------------- user_id 是該表的主鍵(具有唯一值的列)。 該表中的每行包…

FROM stakater/java8-alpine 構建cocker鏡像

在 Dockerfile 中&#xff0c;FROM stakater/java8-alpine 是第一條也是最核心的指令&#xff0c;它定義了構建新鏡像所基于的「基礎鏡像」。以下是逐層解析&#xff1a;&#x1f50d; 關鍵字拆解 1. FROM —— 起點指令 ? 作用&#xff1a;聲明當前鏡像的起點&#xff08;父鏡…

Word2Vec模型訓練全流程解析:從數據預處理到實體識別應用

請添加圖片描述 訓練Word2Vec模型 概述 問題 我們如何訓練Word2Vec模型&#xff1f;在特定數據集上訓練Word2Vec模型何時是有利的&#xff1f; 目標 理解在自有數據上訓練Word2Vec模型而非使用預訓練模型的優勢 Colab環境配置 運行以下代碼以啟用輔助函數并重新讀取數據…

在Ubuntu上使用QEMU學習RISC-V程序(2)gdb調試

文章目錄一、準備工作二、基本調試流程1. 設置斷點2. 執行程序3. 查看源代碼/匯編三、查看寄存器1. 查看通用寄存器2. 查看特殊寄存器四、查看內存1. 內存查看命令2. 內存修改命令五、調試實戰示例六、高級調試技巧1. 條件斷點2. 自動顯示3. 內存斷點&#xff08;觀察點&#x…