嵌入式C語言11(宏/程序的編譯過程)

? 基本概念

C語言中可以利用宏定義實現文本的快速替換,注意:宏定義是單純的文本替換,不檢查語法是否合法。

C語言標準中提供了很多的預處理指令,比如#include、#pragma…以#開頭的都屬于預處理指令。
在這里插入圖片描述
在這里插入圖片描述
預處理指令指的是在gcc編譯套件中的cpp預處理器對程序進行編譯之前所做的一些動作,比如#include預處理指令就是在程序編譯之前由預處理器把包含的頭文件中的代碼拷貝一份到源文件對應的位置,如果包含的文件中還有其他的預處理指令,會遞歸執行!
在這里插入圖片描述
C語言標準中還提供了#define預處理指令,define是C語言關鍵字之一,中文具有定義的含義,所以利用#define預處理指令可以對某些表達式、某些常量、某些函數進行定義,其實就是給這些內容起一個可讀性較高的名稱。

定義格式

在這里插入圖片描述
宏替換其實就是簡單的文本替換,宏名稱就是一個用戶命名的特定的標識符,一般實際開發中宏名稱都采用大寫(潛規則)。 macro 宏

宏名稱后面就是用來替換宏名稱的替換列表,這個替換列表可以是常量、表達式、if語句以及函數等。

定義格式: #define 宏名稱(大寫) 替換列表 換行(一般就是用戶按下回車)
在這里插入圖片描述
用戶在源文件中某個位置使用了宏,不管使用了多少次,在程序編譯之前,預處理器都會把宏用替換列表進行替換,當然要注意,宏替換就是單純的文本替換,預處理器并不會做任何檢查,比如替換之后是否符合語法,語法的檢查是由編譯器在編譯階段進行的。
在這里插入圖片描述
在這里插入圖片描述

使用規則

注意:宏定義的作用域是針對整個文件有效,所以應該定義在源文件的開頭部分,這樣才可以在其他的函數中使用宏定義,另外,宏不是語句,所以不需要在末尾添加分號,如果添加分號,則分號也會被一起替換。
在這里插入圖片描述

具體分類

C語言中宏定義的方案有三種,分別是無參數宏、帶參數宏、無替換列表宏,具體如下所示:

(1) 無參數的宏定義
注意:除了用戶自定義的宏之外,系統中也存在一些已經定義好的宏,比如常用的NULL就是一個宏,當然,C99標準中還有一些常用的系統預定義的宏:
在這里插入圖片描述
(2) 帶參數的宏定義
C語言標準中支持定義帶參數的宏,帶參數的宏的使用在語法上類似于函數調用,宏的參數由括號()進行包含,括號中如果有多個參數則需要通過逗號來分隔,另外,帶參數的宏在定義的時候宏名稱和參數列表之間不能空格,如下所示:
在這里插入圖片描述
可以發現,帶參數的宏和函數的形式很像,但是卻完全不同,帶參數的宏會在程序所有出現的位置進行展開,缺點是浪費了內存空間,但是節約了函數切換的時間。
在這里插入圖片描述
(3) 無替換列表的宏

C語言中也允許只定義一個宏,這個宏可以沒有替換列表,一般實際開發中都是對程序進行條件編譯的情況下來使用。

條件編譯指的是可以選擇性的編譯程序中的某段代碼,也就是預處理器可以根據具體的條件來保留或者刪除某段源程序。

可以理解為是類似于C語言的判斷語句,只不過是使用C語言中的預處理指令來判斷宏的有效性,有效性指的是宏是否為真以及宏是否存在,C語言中提供了多種預處理指令來實現條件編譯。

在這里插入圖片描述
A. #if 用于判斷常量表達式是否成立,遵循“非0即真”原則,#if預處理指令作為條件編譯
在這里插入圖片描述
在這里插入圖片描述
一般#if和#endif是結合一起使用的,經常用于程序中的調試,可以選擇保留或注釋代碼塊!

B. #ifdef 用于判斷宏是否被定義,如果宏是提前定義好的,則該預處理指令是有效的,也需要和#endif一起使用
在這里插入圖片描述
C.#if和#elif和#else和#endif 用于條件編譯,可以通過常量表達式的多種狀態來選擇保留或者刪除某些代碼塊
在這里插入圖片描述
D. #ifndef和#endif 用于判斷宏是否未定義,如果宏定義,則該代碼塊會被刪除,如果宏未被定義,則該代碼塊可以保留
在這里插入圖片描述
在這里插入圖片描述

作用范圍

思考:宏定義一般定義在源文件的開頭,所以作用域是針對整個文件,但是有的時候如果只打算讓某個宏只對某個函數有效,請問應該如何實現?

回答:可以實現,可以利用C語言標準中提供的預處理指令#undef,可以提前終止某個宏的作用域。
在這里插入圖片描述

程序的編譯過程

思考:什么叫做預處理階段?預處理階段和編譯階段有什么不同?源文件轉換為可執行文件一共需要經歷幾個階段?
在這里插入圖片描述
預處理:
對源碼進行簡單的加工,GCC編譯器會調用預處理器cpp對程序進行預處理,其實就是解釋源程序中所有的預處理指令,如#include(文件包含)、#define(宏定義)、#if(條件編譯)等以#號開頭的預處理語句。

這些預處理指令將會在預處理階段被解釋掉,如會把被包含的文件拷貝進來,覆蓋掉原來的#include語句,把所有的宏定義展開,所有的條件編譯語句被執行,GCC還會把所有的注釋刪掉,添加必要的調試信息。

預處理指令: gcc -E xxx.c -o xxx.i 會生成預處理文件 xxx.i

編譯:
就是對經過預處理之后的.i文件進行進一步翻譯,也就是對語法、詞法的分析,最終生成對應硬件平臺的匯編文件,具體生成什么平臺的匯編文件取決于編譯器,比如X86平臺使用gcc編譯器,而ARM平臺使用交叉編譯工具arm-linux-gcc。

編譯指令 : gcc -S xxx.i -o xxx.s 會生成匯編文件 xxx.s

匯編:
GCC編譯器會調用匯編器as將匯編文件翻譯成可重定位文件,其實就是把.s文件的匯編代碼翻譯為相應的指令。

編譯指令 : gcc -c xxx.s -o xxx.o 會生成目標文件 xxx.o

鏈接:
經過匯編步驟后生成的.o文件其實是ELF格式的可重定位文件,雖然已經生成了指令流,但是需要重定位函數地址等,所以需要鏈接系統提供的標準C庫和其他的gcc基本庫文件等,并且還要把其他的.o文件一起進行鏈接。-lc -lgcc 是默認的,可以省略

編譯指令:gcc hello.o -o hello -lc -lgcc 會生成可執行文件 xxx // l是lib的縮寫

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

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

相關文章

【湖南大學】2025我們該如何看待DeepSeek

大家好,我是櫻木。 DeepSeek 官方網站:https://www.deepseek.com/ 一、DeepSeek 到底是什么? TA 到底厲害在哪里? 故事從 ChatGPT 說起 去年我們看到 Open AI 發布ChatGPT 后,全球的注意力到了 AI 身上。 我們來拆…

【區塊鏈安全 | 第三十三篇】備忘單

文章目錄 備忘單操作符優先級備忘單ABI 編碼和解碼函數bytes 和 string 的成員Address 的成員區塊與交易屬性校驗和斷言數學和加密函數合約相關類型信息函數可見性說明符修飾符備忘單 操作符優先級備忘單 以下是操作符的優先級順序,按評估順序列出: 優先級描述操作符1后綴遞…

Python----計算機視覺處理(Opencv:道路檢測之車道線顯示)

完整版:Python----計算機視覺處理(Opencv:道路檢測完整版:透視變換,提取車道線,車道線擬合,車道線顯示) 一、透視變換 將透視變換之后的圖像再繼續透視變換為原圖像 可參考Python----計算機視…

26屆Java暑期實習面經,騰訊視頻一面

短鏈接的生成原理 如何解決短鏈接生成的哈希沖突問題 如何加快從短鏈接到原鏈接的重定向過程 TCP 和 UDP 協議 如何理解 TCP 是面向連接的 為什么 TCP 的握手是 3 次 IO 模式 是否有真正寫過一個底層的 Socket 通信 MySQL 的事務隔離級別 MVCC 機制 什么叫服務的并行 為什么能基…

Windows注冊鼠標鉤子,獲取用戶選中的文本

注冊鼠標鉤子 // 注冊鼠標鉤子 HHOOK hMouseHook; hMouseHook SetWindowsHookEx(WH_MOUSE_LL, MouseProc, GetModuleHandle(NULL), 0);// 取消鼠標鉤子 UnhookWindowsHookEx(hMouseHook); hMouseHook nullptr; 上述代碼中MouseProc方法用于處理系統的鼠標消息 處理鼠標消息…

flink cdc的source數據流如何配置事件時間,如何設置時間語義,分配時間戳并生成水位線

在 Flink CDC 中為 Source 數據流配置事件時間需要結合時間語義設置、時間戳分配和水位線生成三個核心步驟。以下是具體配置方法及注意事項: 1. 設置時間語義 Flink 默認使用處理時間(Processing Time),需顯式指定事件時間語義&a…

C++ 指針類型轉換全面解析與最佳實踐

文章目錄 C 指針類型轉換全面解析與最佳實踐1. 隱式轉換基類和派生類指針 2. 顯式轉換(1) static_cast(2) dynamic_cast(3) reinterpret_cast(4) const_cast 3. C 風格轉換4. 常見問題與注意事項5. 總結最佳實踐 C 指針類型轉換全面解析與最佳實踐 在 C 中,指針類型…

批量將 txt/html/json/xml/csv 等文本拆分成多個文件

我們的文本文件太大的時候,我們通常需要對文本文件進行拆分,比如按多少行一個文件將一個大的文本文件拆分成多個小的文本文件。這樣我們在打開或者傳輸的時候都比較方便。今天就給大家介紹一種同時對多個文本文件進行批量拆分的方法,可以快速…

ARM 匯編啟動代碼詳解:從中斷向量表到中斷處理

ARM 匯編啟動代碼詳解:從中斷向量表到中斷處理 引言 在嵌入式系統開發中,ARM 處理器(如 Cortex-A 系列)的啟動代碼是系統初始化和運行的基礎。啟動代碼通常包括中斷向量表的創建、初始化硬件狀態(如關閉緩存和 MMU&a…

4.7學習總結 可變參數+集合工具類Collections+不可變集合

可變參數: 示例: public class test {public static void main(String[] args) {int sumgetSum(1,2,3,4,5,6,7,8,9,10);System.out.println(sum);}public static int getSum(int...arr){int sum0;for(int i:arr){sumi;}return sum;} } 細節&#xff1a…

2023年藍橋杯第十四屆CC++大學B組真題及代碼

目錄 1A:日期統計 解析代碼_暴力_正解 2B:01串的熵 解析代碼_暴力_正解 3C:冶煉金屬 解析代碼_暴力_正解 4D:飛機降落 解析代碼_暴力dfs_正解 5E:接龍數列 解析代碼_dp_正解 6F:島嶼個數 解析代…

rom定制系列------小米10pro機型定制解鎖固件 原生安卓15批量線刷固件 操作解析與界面預覽

注意;固件用于自己機型忘記密碼或者手機號注銷等出現設備鎖 過保修期 售后無視的機型,勿用于非法途徑 目前有粉絲聯系,自己的機型由于手機號注銷導致手機更新系統后出現設備鎖界面。另外也沒有解鎖bl。目前無法使用手機。經過詢問是小米10pro機型。根據…

信息學奧賽一本通 1861:【10NOIP提高組】關押罪犯 | 洛谷 P1525 [NOIP 2010 提高組] 關押罪犯

【題目鏈接】 ybt 1861:【10NOIP提高組】關押罪犯 洛谷 P1525 [NOIP 2010 提高組] 關押罪犯 【題目考點】 1. 圖論:二分圖 2. 二分答案 3. 種類并查集 【解題思路】 解法1:種類并查集 一個囚犯是一個頂點,一個囚犯對可以看…

我的NISP二級之路-01

目錄 一.SSE-CMM系統安全工程-能力成熟度模型(Systems Security Engineering - Capability Maturity Model) 二.ISMS 即信息安全管理體系(Information Security Management System),是一種基于風險管理的、系統化的管理體系 三.Kerberos協議 1. 用戶登錄與 AS 請求 2…

WEB安全--內網滲透--利用Net-NTLMv2 Hash

一、前言 在前兩篇文章中分析了NTLM協議中Net-NTLMv2 Hash的生成、如何捕獲Net-NTLMv2 Hash,現在就來探討一下在內網環境中,如何利用Net-NTLMv2 Hash進行滲透。 二、Net-NTLM Hash的破解 工具:hashcat 原理:利用其內部的字典對…

如何正確使用 `apiStore` 進行 API 管理

在現代前端開發中,API 管理是一個非常重要的環節。apiStore 是一個基于 Pinia 的狀態管理工具,它可以幫助我們更高效地管理和調用 API。本文將詳細介紹如何正確使用 apiStore,包括如何創建 API 配置文件、在組件中使用 apiStore 以及如何配置…

瓦片數據合并方法

影像數據 假如有兩份影像數據 1.全球底層影像0-5級別如下: 2.局部高清影像數據級別9-14如下: 合并方法 將9-14文件夾復制到全球底層0-5的目錄下 如下: 然后合并xml文件 使得Tileset設置到最高級(包含所有級別)&…

C++中的類和對象(上)

1 類的定義 1.1 類定義的格式 1 class為定義類的關鍵字,Stack為類的名字,{}中為類的主體,注意類定義結束時后面分號不能省 略》。類體中內容稱為類的成員:類中的變量稱為類的屬性或成員變量; 類中的函數稱為類的方法或者成員函數…

【Tauri2】013——前端Window Event與創建Window

前言 【Tauri2】012——on_window_event函數-CSDN博客https://blog.csdn.net/qq_63401240/article/details/146909801?spm1001.2014.3001.5501 前面介紹了on_window_event,這個在Builder中的方法,里面有許多事件,比如Moved,Res…

【問題處理】webpack4升webpack5,報錯Uncaught ReferrnceError: process is not defined

問題 正在做webpack4升webpack5,項目構建項目成功后在瀏覽器打開時報錯 Uncaught ReferrnceError: process is not defined。 原因 webpack 5 不再自動 polyfill Node.js 的核心模塊。 如果你在瀏覽器運行的代碼中使用它,需要從 NPM 中安裝兼容模塊…