最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊

第 24 講:預(yù)處理指令

2021-10-04 03:27 作者:SunnieShine  | 我要投稿

編譯器指令,或者叫做預(yù)處理指令(Preprocessor),指的是在程序用編譯器翻譯為機(jī)器可以識(shí)別和執(zhí)行的指令前,所做的指令操作。它可以控制程序在不同執(zhí)行狀態(tài)下執(zhí)行不同的結(jié)果。為區(qū)分其他編程語句,我們使用井號(hào) #進(jìn)行開頭。


#include 指令

這個(gè)指令用于導(dǎo)入頭文件。什么是頭文件呢?在使用特定的編程函數(shù),諸如 printf、scanf 等時(shí),由于每一個(gè)編程函數(shù)都有不同的功能,所以為了方便管理,它們各自被放在不同的頭文件下,在使用時(shí),需要根據(jù)它本身屬于哪個(gè)頭文件,先要導(dǎo)入,才能使用。否則編譯器找不到這個(gè)函數(shù)。

它有兩種導(dǎo)入方式:引號(hào)導(dǎo)入和尖括號(hào)導(dǎo)入。如果寫成這樣:

則表示它是一個(gè)系統(tǒng)自帶的編程函數(shù)。它會(huì)先找系統(tǒng)自帶的函數(shù)庫,發(fā)現(xiàn)文件存在就可以打開。如果不存在,再找到你建立這個(gè)C語言程序代碼下,文件夾下是否有這個(gè)頭文件。

反之,如果要先找當(dāng)前文件夾下的頭文件的話,我們使用引號(hào)導(dǎo)入。

注意,編譯器指令都是不用分號(hào)結(jié)尾的。


#define 指令

真·常量定義

它又被稱為宏定義(Macro Defining),是將代碼里所有代碼的寫法替換成宏定義過的寫法。比如,在代碼里寫很多計(jì)算圓的公式,它會(huì)大量使用到圓周率的值(約 3.14159),可如果代碼內(nèi)直接寫值的話,如果需要對代碼作改動(dòng),就需要挨個(gè)改掉它們,就相對麻煩,這個(gè)時(shí)候我們可以使用 #define 指令替換它們,然后改值時(shí),只需要改 #define 一處的值即可。

另外,一般而言,像是這樣的指令寫的東西(3.14159)是一個(gè)常數(shù),所以我們一般將常數(shù)全部大寫變量名,即 PI 的形式,不過這只是一般而言,也可以不大寫。


騷操作

不過,宏定義下的寫法是直接替換的,也就是說,你這么寫完全可以:

只是,一部分 IDE,例如 DevCpp 的編譯器不能執(zhí)行中文字符的宏定義替換罷了。不過,#define 定義語句中間的空格是嚴(yán)格規(guī)定的,只能在 #define 后和定義名稱后有空格,這樣來控制替換,否則系統(tǒng)會(huì)無法判別。


宏定義有時(shí)候也會(huì)背鍋

另外,#define 有一處需要注意的替換。它甚至可以替換函數(shù),但函數(shù)的替換方式可能有一些惡心:

它們是不同的。

看懂了嗎?上面的 ab 都有括號(hào),所以下面替換后,也帶括號(hào);上面沒有括號(hào),下面也沒有括號(hào)。于是根據(jù)優(yōu)先級(jí)的不同,計(jì)算結(jié)果分別是 4 * 6 = 24 和 2 + 6 + 3 = 11。

#undef 指令

甚至還可以使用 #undef 定義名 的方式來撤銷結(jié)束定義。比如

#define 符號(hào)指令

我們也可以在定義符號(hào)的時(shí)候不為其賦值:

這樣定義的符號(hào)在本文件里的任意位置都可以用,或你把它寫進(jìn)頭文件里,然后對其使用了 #include 引入了這個(gè)頭文件時(shí)可用。

這種用法需要配合下面要說到的 #if 指令才能發(fā)揮作用。


#if#else、#elif#endif 指令

這四個(gè)指令單純就是為了和 C++ 語言配合使用得比較多。在 C++ 里,有些常量的定義數(shù)值是和 C 不一致的,好在它提供了 #define 的宏指令指定了語言類別。

在 C++ 里,系統(tǒng)定義了 __cplusplus 符號(hào)。如果我們查看 __cplusplus 符號(hào)是否存在,就可以判斷當(dāng)前使用的文件和語言是 C 語言還是 C++,進(jìn)而去區(qū)分程序的執(zhí)行代碼。

例如上面的 5 行指令,先查詢當(dāng)前代碼環(huán)境是否是 C++。如果是 C++,則會(huì)執(zhí)行第 2 行的 #define 定義語句,讓 NULL 常量定義為 0(這是 C++ 里的定義方式。C++ 的空是用 0 表示而不是 (void *)0 表示的;否則,沒有查到 __cplusplus,說明是 C 語言環(huán)境,那么 NULL 的定義方式就是(void *)0 了。

另外,#if defined 可以簡寫為 #ifdef 指令:

另外,你對條件取反,也是被允許的:

你也可以使用 #ifndef 指令來表達(dá):

最后,你還可以使用嵌套的方式為其定義。實(shí)際上,NULL 常量在頭文件里是這么定義的。

由于頭文件 *.h 是不區(qū)分 C 還是 C++ 語言的,所以保證程序允許正常,這些指令和賦值都是不可少的。#elif 指令類似于 else if 條件判斷,這里就不講了,因?yàn)橛玫臋C(jī)會(huì)很少。


#pragma 雜注指令

最后來說一下雜注(Pragma)。雜注是預(yù)處理指令里最復(fù)雜的一種,這是因?yàn)樗拿帧半s注”就表示了所有亂七八糟的指令,不好取名或用得比較少的時(shí)候,就直接用 #pragma 指令來搞了,所以它的分支也非常多。我們這里來看一些常用的。至于不常用的,如果你碰到了,直接查詢網(wǎng)上給出的文檔即可。


#pragma warning 指令

#pragma warning 指令用于忽略、恢復(fù)和只提示一次警告信息。假如你的代碼里出現(xiàn)了警告錯(cuò)誤,例如下面代碼

這是最基礎(chǔ)的使用 scanf 函數(shù)的方法了。不過編譯器會(huì)提出警告 C6031,提示你忽略了 scanf 的返回值。scanf 的返回值表示正確輸入到變量里的變量總個(gè)數(shù)。如果你輸入了一個(gè)合適的數(shù)字,a 正常賦值,那么這個(gè)返回值就是 1。

它提示這個(gè)信息,提示你最好不要忽略返回值的使用,而是這樣用:

但是,顯然我們沒有必要這么去處理,因?yàn)槲覀冚斎胍粋€(gè)整數(shù)數(shù)值是預(yù)期的,所以我們可以忽略煩人的警告信息,用法是這樣的:

這樣的話,你就看不到后續(xù)使用的所有有關(guān) scanf 上輸入信息的返回值未使用的報(bào)錯(cuò)了。

如果你把代碼改為

表示從此處開始往下的代碼,重新又開始對 C6031 忽略返回值的警告報(bào)錯(cuò)。

這樣則是僅報(bào)告一次這樣的警告信息,其它的都忽略。


#pragma region#pragma endregion 指令

忘了這個(gè)了嗎?這個(gè)就是最開始介紹的,用于分割語義的指令。這兩個(gè)指令是配合使用的,用于分割代碼段,這一段代碼里的所有執(zhí)行內(nèi)容表示某個(gè)含義。另外,寫了這樣的指令后,IDE 就可以識(shí)別這一塊代碼是我們指定好的代碼塊,甚至可以允許我們手動(dòng)折疊和展開它們。


#pragma once 指令

最后一個(gè)指令僅用于頭文件里,表示這個(gè)頭文件只會(huì)被編譯一次。這是因?yàn)?,很多時(shí)候,相同的指令會(huì)被分散放到不同的頭文件里;而反之也可能存在多個(gè)相同名稱的頭文件。這樣的話,如果我們使用 #pragma once 指令可以保證這個(gè)文件整體只會(huì)被編譯一次,防止多次反復(fù)編譯出現(xiàn)隱藏的 bug 和錯(cuò)誤。

當(dāng)然,如果執(zhí)行邏輯都不同的同名頭文件最好還是不要用一樣的頭文件名,防止這些錯(cuò)誤的出現(xiàn)。


第 24 講:預(yù)處理指令的評論 (共 條)

分享到微博請遵守國家法律
陈巴尔虎旗| 太白县| 朝阳区| 龙岩市| 穆棱市| 丹江口市| 库车县| 岳西县| 灵璧县| 林周县| 苍溪县| 西乌| 宁波市| 丰城市| 哈尔滨市| 余姚市| 苏尼特右旗| 松滋市| 丘北县| 岳阳县| 石狮市| 达日县| 甘德县| 曲阳县| 鹤岗市| 商河县| 金山区| 沙河市| 确山县| 抚宁县| 历史| 昂仁县| 武夷山市| 镇安县| 章丘市| 太白县| 广元市| 舒兰市| 化德县| 翁牛特旗| 阜宁县|