作者 謝恩銘,公眾號「程序員聯(lián)盟」(微信號:coderhub)。
轉(zhuǎn)載請注明出處。
原文:http://www.itdecent.cn/p/cb83bb7e9141
《C語言探索之旅》全系列
內(nèi)容簡介
- 前言
- include 指令
- define 命令
- 宏
- 條件編譯
- 總結(jié)
- 第二部分第六課預(yù)告
1. 前言
上一課 C語言探索之旅 | 第二部分第四課:字符串 ,我們結(jié)束了關(guān)于字符串的旅程。
大家在一起經(jīng)歷了前三課:指針、數(shù)組和字符串的“疲勞轟炸”之后,這一課回歸輕松。
就像剛在沙漠里行走了數(shù)日,突然看到一片綠洲,還有準(zhǔn)備好的躺椅,清澈的小湖,冷飲,西瓜,一臺頂配電腦(又暴露了程序員的本質(zhì)...)... 腦補(bǔ)一下這個(gè)畫面還是挺開心的。
前面三課我們一下子學(xué)了不少新知識點(diǎn),雖然我沒有那么"善良",但也不至于不給大家小憩的機(jī)會(huì)啊。
這一課我們來聊聊“預(yù)處理器”,這個(gè)程序就在編譯之前運(yùn)行。
當(dāng)然了,雖然這一課不難,可以作為中場休息,但不要認(rèn)為這一課的內(nèi)容不重要。相反,這一課的內(nèi)容非常有用(讀者:“你就說哪一課的內(nèi)容不是非常有用吧...”)。
2. include 指令
在這個(gè)系列教程最初的某一課里,我們已經(jīng)向大家解釋過:在源代碼里面總有那么幾行代碼是很特別的,稱之為預(yù)處理命令。
這些命令的特別之處就在于它們總是以 # 開頭,所以很容易辨認(rèn)。
預(yù)處理命令有好幾種,我們現(xiàn)在只接觸了一種:以 #include 開始的預(yù)處理命令。
#include 命令可以把一個(gè)文件的內(nèi)容包含到另一個(gè)文件中。
在之前的課程里我們已經(jīng)學(xué)習(xí)了如何用 #include 命令來包含頭文件(以 .h 結(jié)尾的)。
頭文件有兩種,一種是 C語言的標(biāo)準(zhǔn)庫定義的頭文件(stdio.h,stdlib.h,等),另一種是用戶自定義的頭文件。
- 如果要導(dǎo)入 C語言標(biāo)準(zhǔn)庫的頭文件(位于你安裝的 IDE(集成開發(fā)環(huán)境)的文件夾或者編譯器的文件夾里),需要用到尖括號 <>。如下所示:
#include <stdio.h>
- 如果要導(dǎo)入用戶自己項(xiàng)目中定義的頭文件(位于你自己項(xiàng)目的文件夾里),需要用到雙引號。如下所示:
#include "file.h"
事實(shí)上,預(yù)處理器(preprocessor)在編輯之前運(yùn)行,它會(huì)遍歷你的源文件,尋找每一個(gè)以 # 開頭的預(yù)處理命令。
例如,當(dāng)它遇到 #include 開頭的預(yù)處理命令,就會(huì)把后面跟的頭文件的內(nèi)容插入到此命令處,作為替換。
假設(shè)我有一個(gè) C 文件(就是 .c 文件),包含我的函數(shù)的實(shí)現(xiàn)代碼;還有一個(gè) H 文件(就是 .h 文件),包含函數(shù)的原型。
我們可以用下圖來描繪預(yù)處理的時(shí)候發(fā)生的情況:

如上圖所示,H 文件的所有內(nèi)容都將替換 C 文件的那一行預(yù)處理命令(#include "file.h")。
假設(shè)我們的 C 文件內(nèi)容如下所示:
#include "file.h"
int myFunction(int thing, double stuff)
{
/* 函數(shù)體 */
}
void anotherFunction(int value)
{
/* 函數(shù)體 */
}
我們的 H 文件內(nèi)容如下所示:
int myFunction(int thing, double stuff);
void anotherFunction(int value);
編輯之前,預(yù)處理器就會(huì)用 H 文件的內(nèi)容替換那一行 #include "file.h"。
經(jīng)過替換之后,C 文件內(nèi)容如下:
int myFunction(int thing, double stuff);
void anotherFunction(int value);
int myFunction(int thing, double stuff)
{
/* 函數(shù)體 */
}
void anotherFunction(int value)
{
/* 函數(shù)體 */
}
3. define 命令
現(xiàn)在我們一起來學(xué)習(xí)一個(gè)新的預(yù)處理命令,就是 #define 命令。
define 表示“定義”。
這個(gè)命令使我們可以定義預(yù)處理常量,也就是把一個(gè)值綁定到一個(gè)名稱。例如:
#define LIFE_NUMBER 7
我們必須按照以下順序來寫:
#define- 要綁定數(shù)值的那個(gè)名稱
- 數(shù)值
注意:雖然說這里的名稱是大寫字母(因?yàn)榱?xí)慣如此,你也可以小寫),但是這與我們之前學(xué)過的 const 變量還是很不一樣。
const 變量的定義是像這樣的:
const int LIFE_NUMBER = 7;
上面的 const 變量在內(nèi)存中是占用空間的,雖然其不能改變,但是它確確實(shí)實(shí)儲存在內(nèi)存的某個(gè)地方。但是預(yù)處理常量卻不是這樣。
那預(yù)處理常量是怎樣運(yùn)作的呢?
事實(shí)上,預(yù)處理器會(huì)把由 #define 定義的所有的名稱替換成對應(yīng)的值。
如果大家使用過微軟的軟件 Word,那應(yīng)該對“查找并替換”的功能比較熟悉。我們的 #define 就有點(diǎn)類似這個(gè)功能,它會(huì)查找當(dāng)前文件的所有 #define 定義的常量名稱,將其替換為對應(yīng)的數(shù)值。
你也許要問:“用預(yù)處理常量意義何在呢?有什么好處?”
問得好。
第一,因?yàn)轭A(yù)處理常量不用儲存在內(nèi)存里。就如我們之前所說,在編譯之前,預(yù)處理常量都被替換為代碼中的數(shù)值了。
第二,預(yù)處理常量的替換會(huì)發(fā)生在所有引入
#define語句的文件里。如果我們在一個(gè)函數(shù)里定義一個(gè) const 變量,那么它會(huì)在內(nèi)存里儲存,但是如果前面不加 static 關(guān)鍵字(關(guān)于 static,請參看之前的課程)的話,它只在當(dāng)前函數(shù)有效,函數(shù)執(zhí)行完就被銷毀了。然而預(yù)處理常量卻不是這樣,它可以作用于所有函數(shù),只要函數(shù)里有那個(gè)名稱,都會(huì)替換為對應(yīng)的數(shù)值。這樣的機(jī)制在有些時(shí)候是非常有用的。特別對于嵌入式開發(fā),內(nèi)存比較有限,經(jīng)常能看到預(yù)處理常量的使用。
“能否給出一個(gè)實(shí)際使用 #define 的例子呢?”
當(dāng)然可以。例如,當(dāng)你用 C語言來創(chuàng)建一個(gè)窗口時(shí),你需要定義窗口的寬度和高度,這時(shí)候就可以使用 #define 了:
#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 600
看到使用預(yù)處理常量的好處了么?之后如果你要修改窗口的寬度和高度,不必到代碼里去改每一個(gè)值,只需要在定義處修改就好了,非常節(jié)省時(shí)間。
注意:通常來說,
#define語句放在 .h 頭文件中,和函數(shù)原型那些家伙在一起。
如果有興趣,大家可以去看一下標(biāo)準(zhǔn)庫的 .h 文件,例如 stdio.h,你可以看到有不少#define語句。
用于數(shù)組大?。ňS度)的 #define
我們在 C語言編程中也可以使用預(yù)處理常量(#define 語句定義)來定義數(shù)組的大小。例如:
#define MAX_DIMENSION 2000
int main(int argc, char *argv[])
{
char string1[MAX_DIMENSION], string2[MAX_DIMENSION];
// ...
}
你也許會(huì)問:“但是,不是說我們不能在數(shù)組的中括號中放變量,甚至是 const 變量也不可以嗎?”
對,但是 MAX_DIMENSION 并不是一個(gè)變量,也不是一個(gè) const 變量??!就如之前說的,預(yù)處理器會(huì)在編譯之前把以上代碼替換為如下:
int main(int argc, char *argv[])
{
char string1[2000], string2[2000];
// ...
}
這樣有一個(gè)好處,就如之前所說,如果將來你覺得你的數(shù)組大小要修改,可以直接修改 MAX_DIMENSION 的數(shù)值,非常便捷。
在 #define 中的計(jì)算
我們還可以在定義預(yù)處理常量時(shí)(#define 語句中)做一些計(jì)算。
例如,以下代碼首先定義了兩個(gè)預(yù)處理常量 WINDOW_WIDTH(表示“窗口寬度”)和 WINDOW_HEIGHT(表示“窗口高度”),接著我們可以利用這兩個(gè)預(yù)處理常量來定義第三個(gè)預(yù)處理常量:PIXEL_NUMBER(意思是“像素?cái)?shù)目”,等于“窗口寬度” x “窗口高度”),如下:
#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 600
#define PIXEL_NUMBER (WINDOW_WIDTH * WINDOW_HEIGHT)
在編譯之前,PIXEL_NUMBER 會(huì)被替換為 800 x 600 = 480000 。
當(dāng)然預(yù)處理常量對于基本的運(yùn)算:+,-,*,/ 和 % 都是支持的。
注意:用
#define定義預(yù)處理常量時(shí)要盡量多用括號括起來,不然會(huì)出現(xiàn)意想不到的結(jié)果,因?yàn)轭A(yù)處理常量只是簡單的替換。
系統(tǒng)預(yù)先定義好的預(yù)處理常量
我們自己可以定義很多預(yù)處理常量,C語言系統(tǒng)也為我們預(yù)先定義了幾個(gè)有用的預(yù)處理常量。
這些 C語言預(yù)定義的預(yù)處理常量一般都以兩個(gè)下劃線開始,兩個(gè)下劃線結(jié)束,例如:
-
__LINE__:當(dāng)前行號。 -
__FILE__:當(dāng)前文件名。 -
__DATE__:編譯時(shí)的日期。 -
__TIME__:編譯時(shí)的時(shí)刻。
這些預(yù)處理常量對于標(biāo)明出錯(cuò)的地方和調(diào)試是很有用的,用法如下:
printf("錯(cuò)誤在文件 %s 的第 %d 行\(zhòng)n", __FILE__, __LINE__);
printf("此文件在 %s %s 被編譯\n", __DATE__, __TIME__);
輸出如下:
錯(cuò)誤在文件 main.c 的第 10 行
此文件在 Jun 8 2020 09:11:01 被編譯
不帶數(shù)值的 #define
我們也可以像如下這樣定義預(yù)處理常量:
#define CONSTANT
很奇怪吧,后面竟然沒有對應(yīng)的數(shù)值。
以上語句用于告訴預(yù)處理器:CONSTANT 這個(gè)預(yù)處理常量已經(jīng)定義了,僅此而已。雖然它沒有對應(yīng)的數(shù)值,但是它“存在”。
你也許要問:“這樣有什么意義呢?”
這樣做的用處暫時(shí)還不明顯,但是我們在這一課里馬上會(huì)學(xué)到,請繼續(xù)讀下去。
4. 宏
我們現(xiàn)在知道用 #define 語句可以把一個(gè)數(shù)值綁定到一個(gè)名稱上,然后在預(yù)處理階段(編譯之前)預(yù)處理器就可以在代碼里用數(shù)值替換所有的預(yù)處理常量了,非常方便。例如:
#define NUMBER 10
意味著接下來你的代碼里所有的 NUMBER 都會(huì)被替換為 10。是簡單的“查找-替換”。
但是 #define 預(yù)處理命令還可以做更厲害的事。
#define 還可以用來替換… 一整個(gè)代碼體。當(dāng)我們用 #define 來定義一個(gè)預(yù)處理常量,這個(gè)預(yù)處理常量的值是一段代碼的時(shí)候,我們說我們創(chuàng)建了一個(gè)“宏”。
“宏”,英語是 macro。一開始可能不太好理解。這是一個(gè)編程術(shù)語,臺灣一般翻成“巨集”??梢哉f是一種抽象,但在 C語言里就只用于簡單的“查找-替換”。
趣事:之前某網(wǎng)站出現(xiàn)一個(gè)詞:“王力巨集”,原來這個(gè)網(wǎng)站在做簡體中文到繁體中文轉(zhuǎn)換時(shí),把明星“王力宏”的名字中的“宏”替換為了“巨集”,我們的力宏就這么“躺槍”了…
沒有參數(shù)的宏
下面給出一個(gè)很簡單的宏的定義:
#define HELLO() printf("Hello\n");
可以看到,與之前的預(yù)處理常量不太一樣的是:名稱后多了一對括號,我們馬上就來看這有什么用處。
我們用一段代碼來測試一下:
#include <stdio.h>
#define HELLO() printf("Hello\n");
int main(int argc, char *argv[])
{
HELLO()
return 0;
}
運(yùn)行輸出:
Hello
是不是有點(diǎn)意思?不過暫時(shí)還不是那么新穎。
需要理解的是:宏不過是在編譯之前的一些代碼的簡單替換。
上面的代碼在編譯前會(huì)被替換為如下:
int main(int argc, char *argv[])
{
printf("Hello\n");
return 0;
}
如果你理解了這個(gè),那對于宏的基本概念也差不多理解了。
你也許會(huì)問:“那我們每一個(gè)宏只能寫在一行上么?”
不是的,只需要在每一行的結(jié)尾寫上一個(gè) \(反斜杠),就可以開始寫新的一行了,而預(yù)處理器會(huì)把這些行看成一行??梢哉f \ 起到了鏈接的作用。例如:
#include <stdio.h>
#define PRESENT_YOURSELF() printf("您好, 我叫 Oscar\n"); \
printf("我住在浙江杭州\n"); \
printf("我喜歡游泳\n");
int main(int argc, char *argv[])
{
PRESENT_YOURSELF()
return 0;
}
運(yùn)行輸出:
您好,我叫 Oscar
我住在浙江杭州
我喜歡游泳
我們注意到了,調(diào)用宏的時(shí)候,在末尾是沒有分號的。事實(shí)上,因?yàn)?/p>
PRESENT_YOURSELF()
這一行是給預(yù)處理器來處理的,所以沒必要以分號結(jié)尾。
有參數(shù)的宏
我們剛學(xué)習(xí)了無參的宏,也就是括號里沒有帶參數(shù)的宏。這樣的宏有一個(gè)好處就是可以使代碼里經(jīng)常出現(xiàn)的較長的代碼段變得短一些,看起來簡潔。
但是,宏帶了參數(shù)才真正變得有趣起來。
#include <stdio.h>
#define MATURE(age) if (age >= 18) \
printf("你成年了\n");
int main(int argc, char *argv[])
{
MATURE(25)
return 0;
}
運(yùn)行輸出:
你成年了
這樣是不是就有點(diǎn)像函數(shù)了?就是這么酷炫。
上面的宏是怎么運(yùn)作的呢?
age 這個(gè)參數(shù)在實(shí)際調(diào)用宏的時(shí)候,會(huì)被替換為括號里的數(shù)值,這里是 25。所以,整個(gè)宏就替換為了:
if (25 >= 18)
printf("你成年了\n");
不就是我們熟悉的老朋友:if 語句么。
上面的宏定義中,我們也可以用一個(gè) else 來處理“你還未成年”的條件,自己動(dòng)手試一下吧,不難。
當(dāng)然我們也可以創(chuàng)建帶多個(gè)參數(shù)的宏,例如:
#include <stdio.h>
#define MATURE(age, name) if (age >= 18) \
printf("你已經(jīng)成年了,%s\n", name);
int main(int argc, char *argv[])
{
MATURE(32, "Oscar")
return 0;
}
運(yùn)行輸出:
你已經(jīng)成年了,Oscar
好了,對于宏我們需要了解的也差不多介紹完了。如果使用得當(dāng),宏是相當(dāng)有用的。
但是有些時(shí)候,濫用宏也會(huì)產(chǎn)生很多難以調(diào)試的錯(cuò)誤,所以宏是 C語言的一把雙刃劍。
通常我們在 C語言的編程中是不需要經(jīng)常使用宏的,因?yàn)楹暧幸粋€(gè)缺點(diǎn):
宏只是簡單的替換,根本不檢查變量和參數(shù)類型,所以用得不好會(huì)出問題。
不過,很多復(fù)雜的庫,例如擅長圖形界面編程的 wxWidgets 和 Qt,就大量使用了宏。
所以對于宏,我們需要理解。
5. 條件編譯
預(yù)處理命令除了有以上三個(gè)作用以外,還可以實(shí)現(xiàn)“條件編譯”。聽起來有點(diǎn)玄乎,但是只要語文沒有還給小學(xué)體育老師,那應(yīng)該不難理解。
開個(gè)玩笑。我們還是一起來看看如下的例子:
#if 條件1
/* 如果條件1為真,將會(huì)被編譯的代碼 */
#elif 條件2
/* 如果條件2為真,將會(huì)被編譯的代碼 */
#endif
是不是有點(diǎn)類似之前學(xué)過的 if 語句?
可以看到:
- 關(guān)鍵字
#if是一個(gè)條件編譯塊的起始,在后面可以插入一個(gè)條件。 - 關(guān)鍵字
#elif(elif 是 else if 的縮寫)的后面可以插入另一個(gè)條件。 - 關(guān)鍵字
#endif(end 表示“結(jié)束”)是一個(gè)條件編譯塊的結(jié)束。
與 if 語句不同的是,條件編譯沒有大括號。
你會(huì)發(fā)現(xiàn)“條件編譯”是相當(dāng)有用的,它使我們可以按照不同的條件來選擇編譯哪些代碼。
與 if 語句類似,條件編譯塊必須有且只能有一個(gè) #if,可以沒有或有多個(gè) #elif,必須有且只能有一個(gè) #endif。
如果條件為真,那么后面跟著的代碼會(huì)被編譯,如果條件為假,后面的代碼就會(huì)在編譯時(shí)被忽略。
#ifdef 和 #ifndef
現(xiàn)在我們就來看看之前介紹的“沒有數(shù)值的 #define”的用處。
還記得嗎?
#define CONSTANT
我們可以
- 用
#ifdef來表述:“如果此名稱已經(jīng)被定義”。因?yàn)?ifdef 是 if defined 的縮寫,表示“如果已被定義”。 - 用
#ifndef來表述:“如果此名稱沒有被定義”。因?yàn)?ifndef 是 if not defined 的縮寫,表示“如果沒有被定義”。
不得不重提英語對于編程進(jìn)階的重要性,可以參看我之前寫的文章:對于程序員, 為什么英語比數(shù)學(xué)更重要? 如何學(xué)習(xí)
例如我們有如下代碼:
#define WINDOWS
#ifdef WINDOWS
/* 當(dāng) WINDOWS 已經(jīng)被定義的時(shí)候要編譯的代碼 */
#endif
#ifdef LINUX
/* 當(dāng) LINUX 已經(jīng)被定義的時(shí)候要編譯的代碼 */
#endif
#ifdef MAC
/* 當(dāng) MAC 已經(jīng)被定義的時(shí)候要編譯的代碼 */
#endif
可以看到,用這樣的方法,可以很方便地應(yīng)對不同平臺的編譯,使我們的代碼實(shí)現(xiàn)跨平臺。
比如,我要編譯針對 Windows 系統(tǒng)的代碼,那就在開始處寫:
#define WINDOWS
我要編譯針對 Linux 系統(tǒng)的代碼,那就改成:
#define LINUX
如果是 macOS 系統(tǒng),那就改成:
#define MAC
當(dāng)然了,每次修改代碼之后都要重新編譯(畢竟沒有那么神奇)。
使用 #ifndef 來避免“重復(fù)包含”
#ifndef 是非常有用的,經(jīng)常用于 .h 頭文件中,以避免“重復(fù)包含”。
什么是“重復(fù)包含”呢?
其實(shí)不難理解,設(shè)想以下情況:
我有兩個(gè)頭文件,分別命名為 A.h 和 B.h 。在 A.h 中我寫了
#include "B.h"
而不巧在 B.h 中我寫了
#include "A.h"
要知道,在代碼復(fù)雜度提高以后,這樣的情況不是不可能發(fā)生的。很多時(shí)候,我們一個(gè)文件里要 inculde 好多個(gè)頭文件,很容易暈。
這樣一來,A.h 文件需要 B.h 來運(yùn)行,而 B.h 文件需要 A.h 來運(yùn)行。
如果我們稍加思索,就不難想到會(huì)發(fā)生什么:
電腦讀入 A.h 文件,發(fā)現(xiàn)需要包含 B.h。
電腦在 A.h 中包含進(jìn) B.h 文件的內(nèi)容,可是在 B.h 文件的內(nèi)容里又發(fā)現(xiàn)需要包含 A.h。
如此循環(huán)往復(fù),什么時(shí)候是個(gè)頭啊…
你肯定認(rèn)為這會(huì)永不止息…
事實(shí)上,碰到這種情況,預(yù)處理器會(huì)停止,并且拋出“我受不了這么多包含啦!”的錯(cuò)誤,你的程序就不能通過編譯。
那如何來避免這樣的悲劇呢?
下面就是解方。并且從今以后,我強(qiáng)烈建議大家在每一個(gè) .h 頭文件中都這樣做!讓我任性一回吧...
#ifndef DEF_FILENAME // 如果此預(yù)處理常量還未被定義,即是說這個(gè)文件未被包含過
#define DEF_FILENAME // 定義此預(yù)處理常量,以避免重復(fù)包含
/* file.h 文件的內(nèi)容 (其他的 #include,函數(shù)原型,#define,等...) */
#endif
如上所示,在 #ifndef 和 #endif 之間我們放置 .h 文件的內(nèi)容(其他的 #include,函數(shù)原型,#define,等)。
我們來理解一下到底這段代碼是怎么起作用的?(我自己第一次碰到這個(gè)技術(shù)時(shí)也有點(diǎn)不太理解):
假使我們的 file.h 文件是第一次被包含(被 include),預(yù)處理器讀到開頭的那句話:
#ifndef DEF_FILENAME
意思是“DEF_FILENAME 這個(gè)預(yù)處理常量還沒有被定義”,這個(gè)條件是真的。所以預(yù)處理器就進(jìn)入 #if 語句內(nèi)部啦(和普通的 if 語句類似的機(jī)制)。
接著預(yù)處理器就讀到第二句命令:
#define DEF_FILENAME
這句的意思是“定義 DEF_FILENAME 這個(gè)預(yù)處理常量”。所以預(yù)處理器乖乖地執(zhí)行,定義 DEF_FILENAME。
接著它就將 file.h 頭文件的主體內(nèi)容都包含進(jìn)調(diào)用 #include "file.h" 或者 #include <file.h> 的那個(gè)文件。
這樣的話。下一次這個(gè) file.h 頭文件再被其他文件包含時(shí),`
#ifndef DEF_FILENAME
這個(gè)條件就不為真了,預(yù)處理器就不會(huì)執(zhí)行條件編譯內(nèi)部的語句了,自然就不會(huì)再把頭文件的主體內(nèi)容包含了。
這樣就能巧妙地避免“重復(fù)包含”。
當(dāng)然,那個(gè)預(yù)處理常量的名稱不一定要和我的一樣,也不一定要大寫,但是最好大寫,是約定俗成的用法。
但是每一個(gè)頭文件的所用常量名稱必須不同,否則,只有第一個(gè)頭文件會(huì)被包含。
非常建議大家有空去看一下標(biāo)準(zhǔn)庫的頭文件,如 stdio.h,stdlib.h,等。你會(huì)發(fā)現(xiàn)它們都是以這樣的方式寫的(開頭 #ifndef,結(jié)尾 #endif)。
6. 總結(jié)
預(yù)處理器是這樣一個(gè)程序,它在編譯之前執(zhí)行,它先分析源代碼,然后做出一定修改。
預(yù)處理命令有好幾種。
#include命令用于在一個(gè)文件中插入另一個(gè)文件的內(nèi)容。#define命令定義一個(gè)預(yù)處理常量。之后預(yù)處理器就會(huì)把代碼里所有#define定義的常量名稱替換成對應(yīng)的值。宏是一些代碼塊,定義也要借助
#define。宏可以接受參數(shù)。我們也可以用預(yù)處理器的語言來寫一些預(yù)處理?xiàng)l件,以實(shí)現(xiàn)條件編譯。一般我們使用關(guān)鍵字:
#if,#elif和#endif等。為了防止一個(gè)頭文件被多次包含,我們會(huì)用條件編譯和預(yù)處理常量的組合來“保護(hù)”它。之后我們寫的 .h 頭文件都會(huì)采用這種方式,也很建議采用。
7. 第二部分第六課預(yù)告
今天的課就到這里,一起加油吧!
下一課:C語言探索之旅 | 第二部分第六課:創(chuàng)建你自己的變量類型
我是 謝恩銘,公眾號「程序員聯(lián)盟」(微信號:coderhub)運(yùn)營者,慕課網(wǎng)精英講師 Oscar 老師,終生學(xué)習(xí)者。
熱愛生活,喜歡游泳,略懂烹飪。
人生格言:「向著標(biāo)桿直跑」