国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【C語(yǔ)言趣味教程】(1) 深入淺出 HelloWorld:通過 HelloWorld 展開教學(xué) | 頭文件詳解 | main 函數(shù)詳解

這篇具有很好參考價(jià)值的文章主要介紹了【C語(yǔ)言趣味教程】(1) 深入淺出 HelloWorld:通過 HelloWorld 展開教學(xué) | 頭文件詳解 | main 函數(shù)詳解。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

?c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?? 《C語(yǔ)言趣味教程》?? 猛戳訂閱?。?!


  • ?? 寫在前面:這是一套?C 語(yǔ)言趣味教學(xué)專欄,目前正在火熱連載中,歡迎猛戳訂閱!本專欄保證篇篇精品,繼續(xù)保持本人一貫的幽默式寫作風(fēng)格,當(dāng)然,在有趣的同時(shí)也同樣會(huì)保證文章的質(zhì)量,旨在能夠產(chǎn)出?"有趣的干貨" !

    本系列教程不管是零基礎(chǔ)還是有基礎(chǔ)的讀者都可以閱讀,可以先看看目錄!?標(biāo)題前帶星號(hào) (*) 的部分不建議初學(xué)者閱讀,因?yàn)閮?nèi)容難免會(huì)超出當(dāng)前章節(jié)的知識(shí)點(diǎn),面向的是對(duì) C 語(yǔ)言有一定基礎(chǔ)或已經(jīng)學(xué)過一遍的讀者,初學(xué)者可自行選擇跳過帶星號(hào)的標(biāo)題內(nèi)容,等到后期再回過頭來(lái)學(xué)習(xí)。

    值得一提的是,本專欄?強(qiáng)烈建議使用網(wǎng)頁(yè)端閱讀!?享受極度舒適的排版!你也可以展開目錄,看看有沒有你感興趣的部分!?本章是本教程的開篇之作,篇幅較長(zhǎng)且內(nèi)容極為豐富 (全文近兩萬(wàn)字),是本團(tuán)隊(duì) (只有我一個(gè)人的團(tuán)隊(duì)) 嘔心瀝血耗時(shí)一周打磨出來(lái)的內(nèi)容,希望需要學(xué)?C 語(yǔ)言的朋友可以耐下心來(lái)讀一讀。最后,可以訂閱一下專欄防止找不到。

" 有趣的寫作風(fēng)格,還有特制的表情包,而且還干貨滿滿!太下飯了!"

—— 沃茲基碩德

?? 本章目錄:

Ⅰ.?你好, 世界?。℉ello World)

0x00 引入:HelloWorld 的由來(lái)

0x01 代碼編輯器的選用(推薦 VS2022)

0x02 創(chuàng)建新項(xiàng)目

0x03?敲下這 “跨越歷史” 的 Hello World!

Ⅱ. 頭文件(Header)

0x00?引入:什么是頭文件?

0x01?標(biāo)準(zhǔn)輸入輸出庫(kù) stdio

0x02 引入頭文件的方式

* 0x03 養(yǎng)成聲明與定義分離的習(xí)慣

* 0x04?頭文件保護(hù)(防止頭文件重復(fù)包含)

* 0x05 條件引用技術(shù)

* 0x06?實(shí)踐錯(cuò)誤記錄:#include 展開的問題

* 0x07?技巧:學(xué)會(huì)定義 _GLOBAL_H 來(lái)管理頭文件

* 0x08 整理:stdio 定義的庫(kù)變量、庫(kù)宏和庫(kù)函數(shù)

Ⅲ.? main 函數(shù)(Main Function)

0x00 引入:繼續(xù)觀察 HelloWorld 示例

0x01 什么是 main 函數(shù)?

0x02?常規(guī)寫法: int main() 和 int main(void)

* 0x03?帶參寫法:int main(int argc, char *argv[])

* 0x04?頗有爭(zhēng)議的寫法:void main()

* 0x05?存在于 C89 的寫法:main()

* 0x06?錯(cuò)誤寫法:mian()

* 0x07?main 函數(shù)執(zhí)行前做的事

* 0x08 可以調(diào)用 main 函數(shù)嗎?

Ⅳ. 深入淺出:Hello,World!

0x00 引入:再看 Hello,World!

0x01 函數(shù)體的概念(花括號(hào)匹配原則)

0x02?簡(jiǎn)單介紹一下 printf 函數(shù)

0x03 分號(hào),語(yǔ)句結(jié)束的標(biāo)志!

0x04 返回語(yǔ)句 return?

* 0x05 關(guān)于?return 后面帶括號(hào)的寫法

0x06 深入淺出:Hello,World!

尾記:如何學(xué)習(xí)一門編程語(yǔ)言?


Ⅰ.?你好, 世界!(Hello World)

  • 本章是首個(gè)章節(jié),將通過計(jì)算機(jī)最經(jīng)典的示例程序 ?Hello World 來(lái)展開我們的教程,考慮到 C 語(yǔ)言歷史大家應(yīng)該早已屢見不鮮,所以這里我們選擇介紹 Hello World 的歷史和由來(lái)。然后帶著大家創(chuàng)建項(xiàng)目并敲下這最經(jīng)典的代碼。

0x00 引入:HelloWorld 的由來(lái)

"所有的偉大,都源于一個(gè)勇敢的開始!"

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃

?? 思考:什么是 Hello World ?它又是怎么來(lái)的?

Hello World 是一種常見的計(jì)算機(jī)程序,通常作為一個(gè)新編程語(yǔ)言或平臺(tái)的入門示例。

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃??它的起源可以追溯到 1974 年,由計(jì)算機(jī)科學(xué)家?布萊恩·柯林漢?創(chuàng)造。

沒錯(cuò),就是那個(gè)?80 歲還在咔咔咔寫代碼的巨佬,貝爾實(shí)驗(yàn)室的 神仙?!

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃??在?C 語(yǔ)言第一本教材《C程序設(shè)計(jì)語(yǔ)言》中,

他使用了 Hello World 作為一個(gè)簡(jiǎn)單的示例,來(lái)介紹 C 語(yǔ)言的基本語(yǔ)法。

他與?C 語(yǔ)言之父 ——?丹尼斯里奇?共同合作了撰寫了這本書,K&R?就是兩人名字的縮寫。

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃??同時(shí),他還是開發(fā) Unix 的主要貢獻(xiàn)者,Unix 就是由柯林漢命名的!

"全員惡人?什么惡人?全員神仙!"

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃??可以這么說,當(dāng)你把 Hello World 這幾個(gè)字成功打印到屏幕上時(shí),

你的內(nèi)心體驗(yàn)到的不僅僅是一種成功的喜悅,更重要的是,你正在親身經(jīng)歷一個(gè)跨越歷史的時(shí)刻!

" 編程生涯,由此開始!"

Hello World 究竟從何而來(lái)?

當(dāng) Forbes India 雜志采訪柯林漢時(shí),他本人對(duì)自己這段傳奇故事中一些記憶已經(jīng)有點(diǎn)兒模糊了。當(dāng)被問及為什么選擇 "Hello, World! "時(shí),他回答道:"我只記得,我好像看過一幅漫畫,講述一枚雞蛋和一只小雞的故事,在那副漫畫中,小雞說了一句 Hello World " ——

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃

0x01 代碼編輯器的選用(推薦 VS2022)

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃??剛才我們了解了 Hello World 的故事,敲之前還需要做一些 "必要" 的準(zhǔn)備!正所謂:

" 工欲善其事,必先利其器!"

我們先來(lái)對(duì) "代碼編輯器" 做一個(gè)簡(jiǎn)單的了解,我們這里指的 "編輯器" 是 集成開發(fā)環(huán)境 (IDE)?。

集成開發(fā)環(huán)境(即 IDE)是一種軟件應(yīng)用程序,提供了一個(gè)集成的開發(fā)環(huán)境,包括代碼編輯器、編譯器、調(diào)試器和其他開發(fā)工具,用于簡(jiǎn)化和加速軟件開發(fā)的過程。IDE 通常用于軟件開發(fā),尤其是針對(duì)特定編程語(yǔ)言的開發(fā),例如 Java、Python、C++ 等。IDE 的主要優(yōu)點(diǎn)是提供了一個(gè)集成的工作流程,使得開發(fā)人員能夠更加高效地編寫、測(cè)試和調(diào)試代碼。IDE通常具有自動(dòng)代碼完成、語(yǔ)法高亮、代碼調(diào)試、版本控制等功能,可以大大提高開發(fā)效率和代碼質(zhì)量。常見的 IDE 包括 Visual Studio、Eclipse、和 IntelliJ IDEA 等。

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃??下面我先打開我的編輯器,我的代碼編輯器是:

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃??大人!時(shí)代變了!怎么還有人在用 VC6.0??。〔粫?huì)吧?

哈哈哈哈哈,怎么會(huì)!我用的可是支持腦機(jī)接口編程的?VS2077?:

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?

開個(gè)玩笑,其實(shí)是 VS2022!本系列博客 Windows 系統(tǒng)下一律選用 Visual Studio 2022?

我們也是非常推薦大家使用 VS2022 的,臣以為 VS2022 真乃 宇宙最強(qiáng)編輯器 也!

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?

" 強(qiáng)烈建議安裝,用過都說好,下載鏈接我貼到下面了。"

?? VS 官網(wǎng):Visual Studio 2022 IDE - 適用于軟件開發(fā)人員的編程工具

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?

學(xué)習(xí)階段我們使用免費(fèi)的 Community2022 版本 (社區(qū)版) 就完全夠用了,大家可以自行下載。

關(guān)于為什么選用 VS


關(guān)于 Visual Studio 的安裝,網(wǎng)上有很多很不錯(cuò)的教學(xué)視頻,簡(jiǎn)易大家跟著視頻去安裝。?安裝過程還是沒有什么難度的,喝杯咖啡的功夫就可以搞定了!和安裝 Java 環(huán)境比真的容易太多,Java 還要手動(dòng)配置環(huán)境,設(shè)置電腦環(huán)境變量等一系列雜七雜八的工作…… 而 Visual Studio?非常人性化地一條龍服務(wù),幾乎幫你包攬了這一切?。ㄟ€有個(gè)編輯器叫CLion,J家的開包即用的編輯器,但本專欄還是選用了?VS)

此外,微軟還有一個(gè)叫 Vscode 的神器,這個(gè)環(huán)境的準(zhǔn)備就復(fù)雜得多,我們也不簡(jiǎn)易新手一上來(lái)就用 Vscode(雖然我當(dāng)年系統(tǒng)性學(xué)C的時(shí)候就直接搗鼓了?Vscode 環(huán)境),安裝環(huán)境的過程是非常勸退人的,所以也不建議。值得一提的是,Vscode 屬于輕量化的編輯器,并不是?IDE!

當(dāng)然有些學(xué)??赡軙?huì)要求大家使用 Dev C++,那個(gè)也是個(gè)不錯(cuò)的編輯器,但是還是建議大家去使用?Visual Studio,因?yàn)楹罄m(xù)章節(jié)中會(huì)附帶一些基礎(chǔ)調(diào)試的教學(xué),是基于?Visual Studio 的,本專欄在 Window 下也都是采用?Visual Studio 來(lái)給大家做教學(xué)演示的,所以為了更好地貼合本專欄進(jìn)行系統(tǒng)性地學(xué)習(xí),盡量選用?Visual Studio!?(ps:再多說一句:如果你學(xué)校推薦的編譯器是 VC6.0 + 和用到包漿的 PPT,額…… )

* 當(dāng)然,為了更方便大家系統(tǒng)性地學(xué)習(xí),后期我會(huì)更新一篇 VS 的安裝教程的。

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?下面,我們將認(rèn)為讀者已經(jīng)安裝好了 VS2022,并帶著大家手把手敲出 Hello,World!

?? 注意:所以為了更好地貼合本專欄進(jìn)行系統(tǒng)性地學(xué)習(xí),盡量選用?Visual Studio?!

0x02 創(chuàng)建新項(xiàng)目

?首先,找到桌面快捷方式,雙擊打開?Visual Studio 2022

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?(簡(jiǎn)約而不失優(yōu)雅的加載頁(yè)面...)

?進(jìn)入下方頁(yè)面后,點(diǎn)擊右下角的?創(chuàng)建新項(xiàng)目 (N)

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?

?然后點(diǎn)擊?空項(xiàng)目

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?

隨后到了配置新項(xiàng)目,這里創(chuàng)建項(xiàng)目名稱,演示階段名字自行取,之后點(diǎn)擊 創(chuàng)建 (C)?

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?

創(chuàng)建完新項(xiàng)目后,我們找到 解決方案資源管理器,右鍵 "源文件",點(diǎn)擊 "添加新建項(xiàng)" :

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?名稱我們就取為 test.c,然后點(diǎn) 添加(A),我們的工程就會(huì)在指定的位置很好地創(chuàng)建出來(lái):

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃??這里的 .c 文件 和 .h 以及 VS 默認(rèn)的 .cpp 后綴是什么?我們來(lái)簡(jiǎn)單介紹一下:

簡(jiǎn)而言之,.c?文件用于 C 語(yǔ)言編程,.cpp?文件用于 C++ 編程:

  • .c 是 C?源代碼文件的擴(kuò)展名。
  • .cpp 是 C++ 源代碼文件的擴(kuò)展名。
  • .h 是頭文件 (header file) ,包含在 C 或 C++ 程序中,用于聲明函數(shù)、變量和數(shù)據(jù)結(jié)構(gòu)等,以便在程序的其他部分中使用。

(這些我們?cè)诤笃谥v解 編譯鏈接 時(shí)都會(huì)詳細(xì)講解,這里只需要 .c 是 C 語(yǔ)言源文件的后綴即可)

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?創(chuàng)建完畢后,我們就可以在 test.c?下打代碼了:

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃??至此,我們要做的準(zhǔn)備工作基本就完成了,下面我們就要開始敲 Hello,World 了!

0x03?敲下這 “跨越歷史” 的 Hello World!

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃??如果你是一個(gè)初學(xué)者,我們很能理解你迫切的想要敲出 Hello,World 的心情!

我們現(xiàn)在就拉出本教程的第一個(gè)代碼 —— Hello,World,來(lái)讓大家 一睹芳容 !

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?

" 手動(dòng)播放勁爆的新寶島 bgm,敲下這令人激動(dòng)的第一個(gè)代碼!"

?? 代碼演示:C 語(yǔ)言經(jīng)典示例程序 —— Hello,World

#include <stdio.h>

int main()
{
	printf("Hello, World!\n");

	return 0;
}

你可以手動(dòng)將代碼打到源文件中,也可以直接點(diǎn)擊右上角 "復(fù)制" 按鈕,將代碼粘貼到源文件中。

下面我們準(zhǔn)備運(yùn)行這段代碼,點(diǎn)擊頂部菜單欄 調(diào)試 (D) → 開始執(zhí)行(不調(diào)試)?

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃??當(dāng)然你也可以使用快捷鍵運(yùn)行,輸入?Ctrl + F5?運(yùn)行代碼:

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?

我們也推薦大家使用!因?yàn)樽鳛殒I盤俠,使用快捷鍵會(huì)很 cool !

運(yùn)行后就會(huì)彈出一個(gè)窗口 ——?Microsoft Visual Stidio?調(diào)試控制臺(tái):

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?

我們可以看到,我們的 Hello, World! 在控制臺(tái)上出現(xiàn)了,這是因?yàn)槲覀冋{(diào)用了打印函數(shù) printf

#include <stdio.h>

int main()
{
	printf("Hello, World!\n");  ?? 打印 Hello,World

	return 0;
}

(如果是零基礎(chǔ)讀者,看不明白這段代碼,這都沒有關(guān)系,我們會(huì)深入淺出地慢慢講解)

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃??只會(huì)敲 Hello World 的我瑟瑟發(fā)抖……

至此,我們的 Hello World 就敲完了,我們也成功的將這段話輸出到了我們的顯示器上。

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?下面我們會(huì)慢慢地、深入淺出地講解剛才的 Hello World 代碼:

#include <stdio.h>

int main()
{
	printf("Hello, World!\n");  

	return 0;
}

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃??等講解完這些必要的知識(shí)點(diǎn)后,我們?cè)倩貋?lái)看這段代碼,就會(huì)非常地清楚 ~

Ⅱ. 頭文件(Header)

  • 圍繞著 HelloWorld 繼續(xù)推進(jìn),理解第一行代碼我們需要先知道什么是頭文件,以及我們引入的 stdio 庫(kù),這里我們會(huì)詳細(xì)的講解各種頭文件的知識(shí)點(diǎn),包含了頭文件保護(hù)、聲明定義分離、#include 展開等內(nèi)容。

0x00?引入:什么是頭文件?

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?下面是 HelloWorld 示例程序的第一行代碼:

#include <stdio.h>    // 引入頭文件 stdio 庫(kù)

* 注:兩個(gè)斜杠 (?//?) 后面的內(nèi)容屬于「注釋」,我們會(huì)在下一章進(jìn)行講解!

這一行代碼的意思是 "引入頭文件 stdio.h 庫(kù)",我們先來(lái)簡(jiǎn)單介紹一下什么是 頭文件?(header)。

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?

?? 概念:頭文件,?[英] header,[繁] 標(biāo)頭檔

后綴為 .h 的文件被稱為 "頭文件" ,因?yàn)轭^文件的英文是 header,所以縮寫為 .h 。

包含了 C 語(yǔ)言函數(shù)聲明和宏定義,被多個(gè)源文件中引用共享。

頭文件分為兩種,一種是 "程序員自己編寫的頭文件",另一種是 "編譯器自帶的頭文件" 。

關(guān)于頭文件的一些細(xì)節(jié)


在 C 語(yǔ)言中,頭文件是一個(gè)文件。頭文件通常是源代碼的形式,由編譯器在處理另一個(gè)源文件時(shí)自動(dòng)包含進(jìn)來(lái)。程序員通過編譯器指令將頭文件包含進(jìn)其他源文件的開始。

一個(gè)頭文件包含類、子程序、變量和其他標(biāo)識(shí)符的前置聲明,需要在一個(gè)以上源文件中生命的標(biāo)識(shí)符可以放在一個(gè)頭文件中,并在需要的地方包含該頭文件。頭文件作為一種包含功能函數(shù)、數(shù)據(jù)接口聲明的載體文件,主要用于保存程序的聲明。

早期的編程語(yǔ)言如 Basic、Fortran 并沒有頭文件的概念。

我們使用 #include 來(lái)引用頭文件,這是一個(gè) C 預(yù)處理指令,對(duì)于預(yù)處理的知識(shí)我們后期會(huì)講解。

#include         引入頭文件

我們的 Hello World 示例代碼中,就是使用了 #include 來(lái)引用頭文件的,引用的是 stdio.h?。

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃??這是什么?下面,我們就來(lái)介紹一下這個(gè) stdio.h。

0x01?標(biāo)準(zhǔn)輸入輸出庫(kù) stdio

stdio.h 是編譯器自帶的頭文件,其中 .h 我們剛才說過,是擴(kuò)展名,被稱之為頭文件。

stdio 全稱 standard input & output,即標(biāo)準(zhǔn)輸入輸出,我們稱之為 C 標(biāo)準(zhǔn)庫(kù),直接看圖記憶:

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?

因?yàn)槲覀兊?HelloWorld 示例程序需要用到 printf 這個(gè)函數(shù),所以我們需要引入 stdio.h

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃??之所以叫做 stdio 是因?yàn)?standard input & output,而它表示了這庫(kù)中最經(jīng)典的兩個(gè)函數(shù):

  • printf() :標(biāo)準(zhǔn)輸入函數(shù)(input)
  • scanf() :標(biāo)準(zhǔn)輸出函數(shù)(output)

(對(duì)于這兩個(gè)函數(shù),我們后續(xù)會(huì)詳細(xì)講解)

?? 了解:stdio.h 的文件說明

/*
*stdio.h
*This file has no copyright assigned and is placed in the Public Domain.
*This file is a part of the mingw-runtime package.
*Now arranty is given;refer to the file DISCLAIMER within the package.
*
*Definitions of types and proto types of functions for 
*standard inputand output.
*
*NOTE:The file manipulation functions provided by Microsoft seem to
*work with either slash(/) or backslash(\) as the directory separator.
*
*/

0x02 引入頭文件的方式

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃??我們前面講了,我們使用 #include 來(lái)引用頭文件,這個(gè) # 是預(yù)處理指令。

預(yù)處理指令 # 可用于宏定義、文件包含 和 條件編譯。

剛才我們介紹了 stdio.h 庫(kù),現(xiàn)在我們?cè)賮?lái)觀察?HelloWorld 示例程序的第一行代碼:

#include <stdio.h>

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃??我們可以看到 #include 后面使用了兩個(gè)尖括號(hào) < > 包住了 stdio.h。

尖括號(hào)中引入的頭文件基本都是 C 語(yǔ)言中各種各樣的?庫(kù)函數(shù),剛才學(xué)習(xí)的 stdio 就是其中之一。

這行代碼中,我們通過 #include <> 去引入了標(biāo)準(zhǔn)輸入輸出庫(kù) stdio。

頭文件的引入除了尖括號(hào) < > ,還有雙引號(hào) " " 形式的引入:

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?

?? 兩種引用方式的區(qū)別:頭文件用 < > 引入和用 " " 引入的區(qū)別

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?首先,< >" " 包含頭文件的本質(zhì)區(qū)別是查找策略區(qū)別。

?尖括號(hào) < > 的查找策略:直接去標(biāo)準(zhǔn)路徑下去查找,用來(lái)引用標(biāo)準(zhǔn)庫(kù)的頭文件。

#include <文件>   // 編譯器將從標(biāo)準(zhǔn)庫(kù)目錄開始搜索

雙引號(hào) " " 的查找策略:先在源文件所在的目錄下查找。如果該頭文件未找到,則在庫(kù)函數(shù)的頭文件目錄下查找。如果仍然找不到,則提示編譯錯(cuò)誤。用來(lái)引用非標(biāo)準(zhǔn)庫(kù)的頭文件。

#include "文件"   // 編譯器將從用戶的工作目錄開始搜索

? 思考:那可不可以用雙引號(hào) " " 包含庫(kù)文件?

#include "stdio.h"

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃??當(dāng)然,庫(kù)文件也是可以使用 " " 包含的,但是不建議庫(kù)文件用 " " 形式引入!

#include <stdio.h> 是庫(kù)文件,你用引號(hào)形式引入 #include "stdio.h" 也是可以的,

但是這樣查找的效率就會(huì)大打折扣,因?yàn)闀?huì)先從源文件所在目錄下去找一遍,然后再去找。

我們既然明確知道自己是要使用庫(kù)文件了,我們自然就直接使用尖括號(hào)才是正常的。

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?而且這樣也不容易區(qū)分是庫(kù)文件還是本地文件。

(看到尖括號(hào)引入就知道是庫(kù)文件,看到引號(hào)引入的就知道是本地文件,還是很香的)

① Linux環(huán)境 標(biāo)準(zhǔn)頭文件的路徑:

/usr/include

② VS環(huán)境 標(biāo)準(zhǔn)頭文件的路徑:

C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include

* 0x03 養(yǎng)成聲明與定義分離的習(xí)慣

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?要做到聲明與定義相分離,頭文件中應(yīng)當(dāng)只存放聲明,而不存放定義。

為了養(yǎng)成模塊化編程的好習(xí)慣,我們盡量把代碼分開寫,聲明放到頭文件中,定義放到源文件中。

VS 下,在解決方案資源管理器中:

  • 在 "頭文件" 文件夾中右鍵取文件名以 .h 結(jié)尾即可創(chuàng)建頭文件。
  • 在 "源文件" 文件夾中右鍵取文件名以 .c 結(jié)尾即可創(chuàng)建源文件。

C++ 語(yǔ)法中,類的成員函數(shù)可以在聲明的同時(shí)被定義,并自動(dòng)成為內(nèi)聯(lián)函數(shù)。這帶來(lái)了書寫上的便利,但也造成了風(fēng)格的不一致,弊大于利。建議將成員函數(shù)的定義與聲明分離開來(lái)。

* 0x04?頭文件保護(hù)(防止頭文件重復(fù)包含)

"使用頭文件保護(hù)技術(shù),能夠有效提升代碼的一致性和可維護(hù)性……"

當(dāng)需要引入多個(gè)頭文件時(shí),頭文件引用條目達(dá)到十幾條以上時(shí),難免會(huì)出現(xiàn)重復(fù)引用的失誤。

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃??比如下面這個(gè)代碼,仔細(xì)觀察你會(huì)發(fā)現(xiàn)不小心引入了兩次 stdio:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <cstdio>
#include <memory>
#include <cstdlib>
#include <random>
#include <cstdio>
#include <stdio.h>     ← 引入兩次了
#include <utility>
#include <cstring>
#include <vector>
#include <functional>
...

這就是典型的重復(fù)引用錯(cuò)誤,此時(shí)編譯器會(huì)處理兩次頭文件的內(nèi)容,從而產(chǎn)生錯(cuò)誤。

為了防止這種情況的發(fā)生,經(jīng)典的做法是將文件的整個(gè)內(nèi)容都放到條件編譯語(yǔ)句中。

具體做法是使用預(yù)處理指令 #ifndef#define#endif 來(lái)避免重復(fù)包含:

#ifndef STDIO_H
#define STDIO_H

// stdio.h 的內(nèi)容

#endif

這里我們使用了包裝器 #ifndef,當(dāng)再次引用頭文件時(shí)條件為假,因?yàn)?STDIO_H 已經(jīng)定義。

如此一來(lái),預(yù)處理器會(huì)檢查 STDIO_H 是否以及定義,如果沒有定義就會(huì)進(jìn)入 #ifndef 塊內(nèi);

如果已經(jīng)定義,此時(shí)預(yù)處理器會(huì)跳過文件的整個(gè)類容,編譯器就會(huì)將其忽略不計(jì)。

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃??該技術(shù)我們稱之為 頭文件保護(hù) (header guards) ,可以有效確保頭文件只被包含一次。

? 如果嫌麻煩,還有一種非常簡(jiǎn)單的方法:

#pragma once // 讓頭文件即使被包含多次,也只包含一份

(具體的講解我們會(huì)在后面的預(yù)處理章節(jié)進(jìn)行更加深刻細(xì)致的講解)

因此,為了預(yù)防頭文件被重復(fù)引入,建議使用 ifndef / define /?endif 結(jié)構(gòu)產(chǎn)生與處理塊。

* 0x05 條件引用技術(shù)

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?條件引用是一種根據(jù)特定條件來(lái)選擇性包含或排除代碼的技術(shù)。

如果需要從多個(gè)不同的頭文件選擇一個(gè)引用到程序中,此時(shí)就需要用?"有條件引用" 來(lái)達(dá)成目的。

舉個(gè)例子,現(xiàn)在我們需要指定不同的操作系統(tǒng)上使用的配置參數(shù):

#if SYSTEM_1
   # include "system_1.h"
#elif SYSTEM_2
   # include "system_2.h"
#elif SYSTEM_3
   ...
#endif

當(dāng)頭文件較多時(shí),此這么做顯然不妥,我們可以預(yù)處理器使用宏來(lái)定義頭文件的名稱。

這種方法就是 有條件引用,不用頭文件的名稱作為 #include 的直接參數(shù),

而只需要用宏名稱代替即可,因?yàn)?SYS_H 會(huì)拓展,預(yù)處理器會(huì)查找 sys_1.h?

 #define SYS_H "sys_1.h"
 ...
 #include SYS_H

(SYSTEM_H 可通過 -D 選項(xiàng)被 Makefile 定義)

* 0x06?實(shí)踐錯(cuò)誤記錄:#include 展開的問題

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃??#include 的展開是有特點(diǎn)的,下面我將通過一個(gè)實(shí)踐中碰到的例子,來(lái)講解展開的特點(diǎn)。

?? 舉個(gè)例子:下面我們手動(dòng)定義了一顆二叉樹(Queue.c)

?
#define _CRT_SECURE_NO_WARNINGS 1
#include "Queue.h"

typedef char BTDataType;
typedef struct BinaryTreeNode {
	struct BinaryTreeNode* left;
	struct BinaryTreeNode* right;
	BTDataType data;
} BTNode;

//#include "Queue.h"  解決方案?

/* 創(chuàng)建新節(jié)點(diǎn) */
BTNode* BuyNode(BTDataType x) {
	BTNode* new_node = (BTNode*)malloc(sizeof(BTNode));
	if (new_node == NULL) {
		printf("malloc failed!\n");
		exit(-1);
	}
	new_node->data = x;
	new_node->left = new_node->right = NULL;

	return new_node;
}

/* 手動(dòng)創(chuàng)建二叉樹 */
BTNode* CreateBinaryTree() {
	BTNode* nodeA = BuyNode('A');
	BTNode* nodeB = BuyNode('B');
	BTNode* nodeC = BuyNode('C');
	BTNode* nodeD = BuyNode('D');
	BTNode* nodeE = BuyNode('E');
	BTNode* nodeF = BuyNode('F');

	nodeA->left = nodeB;
	nodeA->right = nodeC;
	nodeB->left = nodeD;
	nodeC->left = nodeE;
	nodeC->right = nodeF;

	return nodeA;
}

我們可以看到,我們 #include 引入了 Queue.h 文件,由于是我們的數(shù)據(jù)類型是 BTNode,

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?所以我們需要修改一下 Queue.h 中的 QueueDataType

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>

typedef BTNode* QueueDataType;

typedef struct QueueNode {
	struct QueueNode* next;
	QueueDataType data;
} QueueNode;

typedef struct Queue {
	QueueNode* pHead;
	QueueNode* pTail;
} Queue;

void QueueInit(Queue* pQ);                    //隊(duì)列初始化
void QueueDestroy(Queue* pQ);                 //銷毀隊(duì)列
bool QueueIfEmpty(Queue* pQ);                 //判斷隊(duì)列是否為空
void QueuePush(Queue* pQ, QueueDataType x);   //入隊(duì)
void QueuePop(Queue* pQ);                     //出隊(duì)
QueueDataType QueueFront(Queue* pQ);          //返回隊(duì)頭數(shù)據(jù)
QueueDataType QueueBack(Queue* pQ);           //返回隊(duì)尾數(shù)據(jù)
int QueueSize(Queue* pQ);                     //求隊(duì)列大小

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?此時(shí)令人瞠目結(jié)舌的問題就出現(xiàn)了,我們運(yùn)行代碼就會(huì)產(chǎn)生報(bào)錯(cuò):

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?我們來(lái)冷靜分析一下這個(gè)報(bào)錯(cuò),分析完你會(huì)發(fā)現(xiàn)分析了個(gè)寂寞……

報(bào)錯(cuò)說又缺少 " { " 又缺少 " ) "?的,這明顯是胡說八道。

我們的編譯器在這里就顯得沒有這么智能了,報(bào)的錯(cuò)都開始胡言亂語(yǔ)了。

? 思考:這里產(chǎn)生問題的原因是什么呢?(提示:想想編譯器的原則)

?? 編譯器原則:編譯器認(rèn)識(shí) int,是因?yàn)?int 是一個(gè)內(nèi)置類型。但是 BTNode* 編譯器并不認(rèn)識(shí),

就需要 "往上面" 去找這個(gè)類型。這里顯然往上找,是找不到它的定義的,所以編譯器會(huì)報(bào)錯(cuò)。

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?

如果你要用這個(gè)類型,你就需要先定義這個(gè)類型。

test.c 文件中 #include "Queue.h" ,相當(dāng)于把這里的代碼拷貝過去了。

此時(shí),由于 BTNode* 會(huì)在上面展開,導(dǎo)致找不到 BTNode*? 。

? 思考:我把 #include 移到 定義類型的代碼 的后面,可以解決問題嗎?

可以!遺憾的是只能解決這里 typedef BTNode* 的問題,還有 Queue.c 里的問題……

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃??那我們?cè)撛趺醋觯拍軓氐捉鉀Q呢??

?? 解決方案:使用前置聲明。這樣就不會(huì)帶來(lái)問題了,滿足了先聲明后使用。

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?

?? 代碼演示:使用 "前置聲明" 修改后的 Queue.h

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>

// 前置聲明
struct BinaryTreeNode;
typedef struct BinaryTreeNode* QueueDataType;

typedef struct QueueNode {
	struct QueueNode* next;
	QueueDataType data;
} QueueNode;

typedef struct Queue {
	QueueNode* pHead;
	QueueNode* pTail;
} Queue;

void QueueInit(Queue* pQ);                    //隊(duì)列初始化
void QueueDestroy(Queue* pQ);                 //銷毀隊(duì)列
bool QueueIfEmpty(Queue* pQ);                 //判斷隊(duì)列是否為空
void QueuePush(Queue* pQ, QueueDataType x);   //入隊(duì)
void QueuePop(Queue* pQ);                     //出隊(duì)
QueueDataType QueueFront(Queue* pQ);          //返回隊(duì)頭數(shù)據(jù)
QueueDataType QueueBack(Queue* pQ);           //返回隊(duì)尾數(shù)據(jù)
int QueueSize(Queue* pQ);                     //求隊(duì)列大小

此時(shí)問題就解決了,頭文件展開后不會(huì)引發(fā)報(bào)錯(cuò)問題。

* 0x07?技巧:學(xué)會(huì)定義 _GLOBAL_H 來(lái)管理頭文件

"有效避免頭文件過多,亂七八糟,不方便管理的問題。"

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?如果一個(gè)工程中有大量的 .h 文件 和 .c 文件,此時(shí)難免會(huì)很亂。

此時(shí)我們可以選擇用一個(gè) global.h 的頭文件來(lái)把所有?.h 文件 "打包" 起來(lái),

在除 global.h 文件外的頭文件中包含此文件,這樣我們就可以有條不紊地管理好所有的頭文件了。

#ifndef _GLOBAL_H
#define _GLOBAL_H

#include <cstdio>
#include <memory>
#include <cstdlib>
#include <random>
#include <cstdio>
#include <utility>
#include <cstring>
#include <vector>
#include <iostream>
#include <functional>
...

* 0x08 整理:stdio 定義的庫(kù)變量、庫(kù)宏和庫(kù)函數(shù)

?? 專欄閱讀貼士

當(dāng)標(biāo)題前出現(xiàn) *(星號(hào))時(shí),則說明該部分知識(shí)點(diǎn)是面向?qū)?C 語(yǔ)言已經(jīng)有一定基礎(chǔ)的讀者閱讀的,講解時(shí)難免會(huì)穿插不屬于本章范圍的內(nèi)容。如果你是一名初學(xué)者,可以選擇跳過。

對(duì) stdio 有過一些了解的讀者可能會(huì)知道 stdio.h 定義了 3 個(gè)變量類型,以及一些宏和各種函數(shù)。

對(duì)于庫(kù)中的變量、宏和函數(shù),我們一般稱之為 庫(kù)變量、庫(kù)宏?和 庫(kù)函數(shù)。

庫(kù)變量 (Library Variable):

頭文件在 stdio.h 中定義了 3 個(gè)變量類型,分別是?FILE,size_t?fpos_t 類型。

FILE
size_t
fpos_t
  • FILE 類型:存儲(chǔ)文件流信息的對(duì)象類型(文件章節(jié)我們會(huì)詳細(xì)講解)。
  • size_t 類型:無(wú)符號(hào)整數(shù)類型,為關(guān)鍵字?sizeof 的返回結(jié)果。
  • fpos_t 類型:存儲(chǔ)文件中任何位置的對(duì)象類型。

?庫(kù)宏?(Libary Micro):以下是 stdio.h 中定義的宏,一共有 16 種,我們先簡(jiǎn)單介紹一下。

1. NULL

NULL:空指針常量的值。

2. BUFSIZ

BUFSIZ:該宏為整數(shù),代表了 setbuf 函數(shù)使用的緩沖區(qū)大小。

3. EOF

EOF:文件結(jié)束標(biāo)志 EndOfFile,表示文件結(jié)束的負(fù)整數(shù),非常常見!后續(xù)我們學(xué)習(xí) getchar 函數(shù)時(shí)會(huì)詳細(xì)講解。

4. FOPEN_MAX

FOPEN_MAX:該宏為整數(shù),代表了系統(tǒng)可以同時(shí)打開的文件數(shù)量。

5. FILENAME_MAX

FILENAME_MAX:該宏為整數(shù),代表了字符數(shù)組可以存儲(chǔ)的文件名最大長(zhǎng)度,如果事先沒有任何限制,則該值為推薦的最大值。

6. L_tmpnam

L_tmpnam:該宏為整數(shù),代表了字符數(shù)組可以存儲(chǔ)的由 tmpnam 函數(shù)創(chuàng)建的臨時(shí)文件名的最大長(zhǎng)度。

7. _IOFBF
8. _IOLBF
9. _IONBF

拓展了帶有特定值的整型常量表達(dá)式,適用于 setvbuf 的第三個(gè)參數(shù)。

10. SEEK_CUR
11. SEEK_END
12. SEEK_SET

fseek 函數(shù)中使用,用于在一個(gè)文件中定位不同的位置。

13. TMP_MAX

tmpnam 函數(shù)可生成的獨(dú)特文件名的最大數(shù)量。

14. stderr
15. stdin
16. stdout

FILE 類型的指針,標(biāo)準(zhǔn)錯(cuò)誤、標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)輸出流。

庫(kù)函數(shù) (Libary Funciton):共有 42 種函數(shù),我們會(huì)在后續(xù)章節(jié)將一些常用的函數(shù)進(jìn)行介紹。

Ⅲ.? main 函數(shù)(Main Function)

  • 介紹完頭文件后,下面我們將講解 C 程序中最為重要的 main 函數(shù),掌握 main 函數(shù)的特點(diǎn)與特性,探討 main 函數(shù)的各種寫法形式,并對(duì)這些寫法進(jìn)行說明講解。

0x00 引入:繼續(xù)觀察 HelloWorld 示例

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃??剛才我們講解了 #include <stdio.h>,下面我們來(lái)看第三行代碼,int main()?

#include <stdio.h>

int main()
{
	printf("Hello, World!\n");

	return 0;
}

首先,int 表示整型,這里表示 main 函數(shù)的返回值為整型。(下一章我們會(huì)講解數(shù)據(jù)類型)

*?[注]?int 是英文單詞?integer 的縮寫,意思是 "整數(shù)"。

int?后面跟著的 main 就表示了 main 函數(shù),我們先了解下什么是 函數(shù) (function) :

這里的函數(shù)可不是數(shù)學(xué)中的函數(shù),在 C 語(yǔ)言中,函數(shù)是一種可重復(fù)使用的代碼塊,用于執(zhí)行特定的任務(wù)。它是程序的基本組成部分,用于模塊化和組織代碼,使程序更易于理解、調(diào)試和維護(hù)。

0x01 什么是 main 函數(shù)?

?? 概念:main 函數(shù),又稱主函數(shù),每個(gè) C 程序都必須有一個(gè) main 函數(shù)。

#include <stdio.h>

int main()       ?? 程序從這里執(zhí)行
{
	return 0;
}

主函數(shù)是程序執(zhí)行的起點(diǎn),你的程序會(huì)從這里開始執(zhí)行,每次執(zhí)行程序都從 main 函數(shù)開始。

一個(gè)工程中可以有多個(gè) .c 文件,但多個(gè) .c 文件中只能有一個(gè) main 函數(shù),main 函數(shù)具有唯一性。

"一個(gè)程序不能沒有主函數(shù),就像山東不能沒有曹縣!"

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?

?? 鐵律:main函數(shù)是程序的入口,主函數(shù)有且僅有一個(gè)!

一個(gè) C 語(yǔ)言程序的執(zhí)行,從 main 函數(shù)開始,到 main 函數(shù)結(jié)束。 如何理解呢?

你可以把 main 函數(shù)想象成入口,一切都從這里開始執(zhí)行,最后肯定也是要從這出去的。

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?main 函數(shù)的返回類型取決于 main 標(biāo)識(shí)符前是什么數(shù)據(jù)類型,比如這里是 int:

int main() 
{
    return 0;
}

那么該主函數(shù)就存在一個(gè)整型類型的返回值,我們需要使用 return?去返回(我們后續(xù)再說)。

在我們的演示代碼 HelloWorld 中,我們可以看到,main 后面跟了一個(gè)括號(hào),

括號(hào)中定義了函數(shù)的參數(shù)類型,而我們演示代碼中,括號(hào)中是什么都沒有的。

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃??我們可以在括號(hào)里面加上一個(gè) void,就像這樣:

int main(void)

void 也是數(shù)據(jù)類型,表示無(wú)類型,演示代碼中為了演示簡(jiǎn)單化,我們把括號(hào)中的 void 省略掉了。

這里 在括號(hào)中加上 void 表示函數(shù)不接受任何參數(shù), 后面接上的花括號(hào),就是 函數(shù)體 了:

#include <stdio.h>        

int main(void)    // 主函數(shù)的返回類型是 int,主函數(shù) void 不接受任何參數(shù)
{
	printf("Hello, World!\n");

	return 0;     // 由于主函數(shù)要求返回整型,這里 return 0
}

C 語(yǔ)言規(guī)定,在一個(gè)源程序中,main 函數(shù)的位置可以任意。

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?下面我先列舉一些大家常見的主函數(shù)形式,然后我們?cè)俾u(píng)價(jià)。

約定俗成型(目前主流的寫法):

int main()
int main(void)

?什么都不返回型(頗有爭(zhēng)議):

void main()
void main(void)

帶參型(帶參形式,標(biāo)準(zhǔn)的 main 函數(shù),帶兩參數(shù)):

int main(int argc, char **argv)
int main (int argc, char *argv[], char *envp[])

?超級(jí)簡(jiǎn)單型(存在于 C89 標(biāo)準(zhǔn)中的寫法,沒有返回值,沒有入?yún)ⅲ?/p>

main()

// Brian W. Kernighan 和 Dennis M. Ritchie 的經(jīng)典巨著 
// The C programming Language 用的就是 main()。

直接報(bào)錯(cuò)型(相信 90% 的程序員都犯過這個(gè)錯(cuò)誤):

int mian()

0x02?常規(guī)寫法: int main() 和 int main(void)

" 約定俗成型,這應(yīng)該是現(xiàn)在最普遍的寫法了。"

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃??我們平時(shí)寫 main 函數(shù)的時(shí) main 函數(shù)參數(shù)一般都不寫,即括號(hào)里什么都不填。

或者填上一個(gè) void 表示主函數(shù)不接受任何參數(shù):

int main()
int main(void)

?? 注意:值得注意的是,int main() 和 int main(void) 這兩種寫法是存在區(qū)別的!

  • int main():參數(shù)列表沒有被 void 限制死,可以傳入?yún)?shù),程序需要返回值。
  • int main(void):不能傳入?yún)?shù),如果輸入?yún)?shù)就會(huì)報(bào)錯(cuò),程序必須要有返回值。

這兩種寫法中,更加建議加 void 的寫法,因?yàn)槭?C89/C99/C11 標(biāo)準(zhǔn)文檔中提供的寫法之一:

int main(void) { /* ... */ }

* 0x03?帶參寫法:int main(int argc, char *argv[])

" VS下輸入 main 然后回車后就能自動(dòng)補(bǔ)全的標(biāo)準(zhǔn)寫法 "

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?該寫法也是? C89/C99/C11 標(biāo)準(zhǔn)文檔中提供的標(biāo)準(zhǔn)寫法,也是很常見的一種寫法:

int main(int argc, char *argv[]) { /* ... */ }

參數(shù)列表中,argc 是一個(gè)整數(shù)參數(shù),表示傳遞給程序的命令行參數(shù)的數(shù)量。

argv?是一個(gè)指向字符指針數(shù)組的指針,用于存儲(chǔ)命令行參數(shù)的字符串。

  • argv[0]通常是程序的名稱或路徑。
  • argv[1]?到?argv[argc-1]?是傳遞給程序的其他命令行參數(shù)。

?? 代碼演示:int main(int argc, char *argv[])?

#include <stdio.h>

int main(int argc, char *argv[]) 
{
    printf("命令行參數(shù)的數(shù)量:%d\n", argc);
    printf("第一個(gè)參數(shù)(程序名稱):%s\n", argv[0]);

    for (int i = 1; i < argc; i++) 
    {
        printf("參數(shù) %d: %s\n", i, argv[i]);
    }

    return 0;
}

* 0x04?頗有爭(zhēng)議的寫法:void main()

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃??首先拋出一個(gè)事實(shí) —— C/C++ 中從來(lái)沒有定義過 void main()

C++ 之父本賈尼在他的主頁(yè)上的 FAQ 中明確地寫著 ——

The definition void main() {/*...*/} is not and never has been C++, nor has it even been C.

(void main?從來(lái)就不存在于 C++ 或者 C)

void main 這種寫法究竟規(guī)不規(guī)范?這個(gè)廣為大家所知的?void main 究竟是怎么回事?

void main()
void main(void)

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?光從語(yǔ)法角度上來(lái)看,C 語(yǔ)言里是可以編譯運(yùn)行 void main 的。

因?yàn)?C 中的函數(shù)只關(guān)注函數(shù)名,而關(guān)注其返回類型,在找入口函數(shù)時(shí)僅僅在找 "main" 而已。

從匯編角度來(lái)看,返回值即函數(shù)返回時(shí)寄存器? 的值,因此 ?中總是有值的。

和變量一樣,不主動(dòng)賦值給的是隨機(jī)數(shù),因此?void main 即使返回類型是 void,也是有返回值的。

很多人說這種寫法都是 "譚C" 帶的,事實(shí)上并非如此,因?yàn)樵缭谏鲜兰o(jì)就已然出現(xiàn)了這種寫法。

"還有甩鍋給譚C的,更是無(wú)稽之談,難道微軟和 Borland 的工程師也是跟譚C學(xué)的?"

—— 電腦博物館站長(zhǎng)

?c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃??當(dāng)然,一些編譯器?void main 是可通過編譯的,比如 VC6.0?

有人說 void main 其實(shí)挺合理的,編寫單片機(jī)的話你 return 給值給誰(shuí)?

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?此時(shí)出現(xiàn)了一個(gè)非常炸裂的回答:你可以不收,我不能不給。

哈哈哈哈,看來(lái)寫代碼也講人情世故!return 什么無(wú)所謂,我就是要個(gè)態(tài)度 ~?

最后,對(duì) void main 感興趣的朋友可以看此帖:

?? 鏈接:C 語(yǔ)言的「void main」是怎么一代代傳下來(lái)的? - 知乎

* 0x05?存在于 C89 的寫法:main()

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?C89 標(biāo)準(zhǔn)中支持這種只丟一個(gè) main() 的寫法:

main()

C?語(yǔ)言中是調(diào)用者負(fù)責(zé)清棧任務(wù),因此 main 函數(shù)不寫返回參數(shù)依然是可以的。

你看到有人直接扔一個(gè)?main() 但是不報(bào)錯(cuò),事實(shí)上也只是編輯器支持而已。

* 0x06?錯(cuò)誤寫法:mian()

" 因?yàn)檎娴暮苡腥?,所以我不得不提一提?

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?相信很多人都犯過這個(gè)錯(cuò)誤,不小心把 main 打成了?mian……

int mian(void)    

相信很多程序員在職業(yè)生涯中都犯過這個(gè)錯(cuò)誤,看了半天沒看出問題到底出在哪里:

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?

編譯器只會(huì)去找 main,你不小心寫成 mian 編譯器會(huì)說沒找到 main 函數(shù)的。

?? 總結(jié):我們只需老老實(shí)實(shí)地遵循 C 語(yǔ)言標(biāo)準(zhǔn)文檔的兩種寫法,就行了。

int main(void) { /* ... */ }
int main(int argc, char *argv[]) { /* ... */ }

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃??可以保障代碼的通用性和可移植性,沒有 bug,豈不美哉?

* 0x07?main 函數(shù)執(zhí)行前做的事

待更新……

* 0x08 可以調(diào)用 main 函數(shù)嗎?

?? 思考:用戶可不可以調(diào)用 main 函數(shù)?

這個(gè)問題乍一看會(huì)讓人覺得,不可以吧……main 函數(shù)怎么可以讓用戶調(diào)呢:?

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?

很多人都沒有想過這個(gè)問題,但事實(shí)上是可以的,main 函數(shù)是可以遞歸的。

可以是可以,但是調(diào)用會(huì)一直輸出,直至棧溢出(觸發(fā) StackOverflow )。

VS 下觸發(fā)警告:warning C4717: “main”: 如遞歸所有控件路徑,函數(shù)將導(dǎo)致運(yùn)行時(shí)堆棧溢出。

?? 代碼演示:調(diào)用 main()

#include <stdio.h>

int main()
{
	printf("檸檬葉子C\n");
	main();

	return 0;
}

?? 運(yùn)行結(jié)果如下:

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?

Ⅳ. 深入淺出:Hello,World!

  • 最后,我們講講?Hello World 示例程序中剩下來(lái)的部分知識(shí)點(diǎn),引出函數(shù)體的概念,簡(jiǎn)單介紹一下 printf 函數(shù),談?wù)撜Z(yǔ)句結(jié)束的標(biāo)志(分號(hào)),最后講解 return 語(yǔ)句。這些知識(shí)點(diǎn)講完后,我們串聯(lián)前面講的內(nèi)容,就能很清楚地理解 Hello World 了。

0x00 引入:再看 Hello,World!

" 通過這小小的 Hello,World 來(lái)展開我們的教學(xué),豈不美哉?"

#include <stdio.h>

int main(void)
{
	printf("Hello, World!\n");

	return 0;
}

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃??我們剛才講解了頭文件和 main 函數(shù),

現(xiàn)在大家應(yīng)該能理解 #include <stdio.h>int main() 的含義了。

下面我們來(lái)細(xì)說一下 main() 后面接的花括號(hào) { },所以我們先要介紹一下函數(shù)體的概念。

再介紹一下 printf 函數(shù),以及 return 語(yǔ)句,我們的 Hello World 示例程序就可以 "淺出" 了。

0x01 函數(shù)體的概念(花括號(hào)匹配原則)

?? 概念:定義一個(gè)函數(shù)功能的所有代碼組成的整體,稱為 函數(shù)體 (Function Body) 。

函數(shù)體是用花括號(hào)括起來(lái)的若干語(yǔ)句,他們完成了一個(gè)函數(shù)的具體功能。

(函數(shù)聲明與函數(shù)體組成函數(shù)定義,我們會(huì)在函數(shù)章節(jié)詳細(xì)講解)

?? 舉個(gè)例子:比如下面的 main 函數(shù)下面跟著一對(duì)花括號(hào),花括號(hào)內(nèi)的內(nèi)容就是函數(shù)體了。

#include <stdio.h>

int main(void)
{
	printf("Hello, World!\n");

	return 0;
}

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?一對(duì)花括號(hào)?{ } 由 左花括號(hào) {? 和 右花括號(hào) } 組成,左花括號(hào)匹配右花括號(hào)。

比如這里的 main 函數(shù),其 函數(shù)體包括左花括號(hào)和與之匹配的右花括號(hào)之間的任何內(nèi)容

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?

0x02?簡(jiǎn)單介紹一下 printf 函數(shù)

printf("Hello, World!\n");

printf 函數(shù),該函數(shù)是?stdio.h 中的庫(kù)函數(shù),因此在使用前需要使用 #include 引入 stdio.h 。

這里我們就簡(jiǎn)單介紹一下,printf 后面跟著 () ,括號(hào)中的內(nèi)容用雙引號(hào)括出,

雙引號(hào)內(nèi)的內(nèi)容可以輸出到 控制臺(tái),所以我們的 Hello,World 示例程序運(yùn)行后控制臺(tái)會(huì)顯示:

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?

所以,你可以把它叫做 "打印函數(shù)",通過 printf 函數(shù)將 Hello,World 打印到了控制臺(tái)上:

printf("需要打印到控制臺(tái)的內(nèi)容");

? 這里的 \n 為什么沒有被打印出來(lái)?

因?yàn)?\n 是轉(zhuǎn)義字符,用于換行,關(guān)于轉(zhuǎn)義字符的知識(shí)我們會(huì)放到下一章進(jìn)行系統(tǒng)性講解。

0x03 分號(hào),語(yǔ)句結(jié)束的標(biāo)志!

?c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃??在我們?nèi)粘I钪校?"句號(hào)" 表示一段話的結(jié)束。

而在 C 語(yǔ)言中,語(yǔ)句的結(jié)束用 ;?表示,分號(hào)是語(yǔ)句結(jié)束的標(biāo)志,表示一條語(yǔ)句的結(jié)束。

?可以看到,我們的 printf() 函數(shù)后面就有一個(gè) 分號(hào)?;

printf("Hello,World\n");   ?? 加分號(hào)
return 0;    ?? 加分號(hào)

當(dāng)一條語(yǔ)句結(jié)束時(shí),我們需要手動(dòng)給它加上分號(hào),表明該語(yǔ)句結(jié)束。

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?

不加分號(hào)會(huì)報(bào)錯(cuò),人難免是會(huì)忘的,如果忘記加了編譯器會(huì)提示:

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?

隨著敲代碼越來(lái)越熟練,忘記加分號(hào)的情況會(huì)越來(lái)越少的,就像你寫作文不會(huì)忘記加句號(hào)一樣。

遺漏分號(hào)會(huì)引發(fā) C2143 號(hào)報(bào)錯(cuò):error C2143: 語(yǔ)法錯(cuò)誤: 缺少“;”?

當(dāng)然了,也不能在不該加分號(hào)的地方加分號(hào)!

如果你在 main() 后面直接加分號(hào),那就表示語(yǔ)句直接結(jié)束了,后面的 { } 就會(huì)讓編譯器一臉懵……

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?

所以,分號(hào)是初學(xué)者最容易犯錯(cuò)的地方,多用了會(huì)錯(cuò)少用了也會(huì)錯(cuò)。

但是不用擔(dān)心,在后續(xù)學(xué)習(xí)過程中慢慢就會(huì)掌握了。(比如 do...while 語(yǔ)句 while 結(jié)尾要加分號(hào))

0x04 返回語(yǔ)句 return?

我們前面說了,因?yàn)槲覀兊?main 函數(shù)的返回值類型定義的是 int,所以我們需要 return 一個(gè)值:

#include <stdio.h>

int main(void)
{
	printf("Hello, World!\n");

	return 0;
}

?? 概念:在C 語(yǔ)言中,return 用于表示函數(shù)的返回值,用來(lái)將函數(shù)的結(jié)果返回給調(diào)用它的程序。

return 返回值;

因此,這里我們 return 一個(gè) 0,表示程序正常退出。

* 0x05 關(guān)于?return 后面帶括號(hào)的寫法

值得一提的是,return 后面 "不帶括號(hào)" 和?"帶括號(hào)" 的寫法,都是正確的。

return 表達(dá)式;    ? 常規(guī)寫法
return (表達(dá)式);  ? 也是可以的

但是為了簡(jiǎn)單起見,一般我們不去寫,當(dāng)然寫了也不會(huì)錯(cuò),這取決于個(gè)人的編程習(xí)慣。

比如下面這兩行實(shí)際效果是一樣的:

return 10 + 20;
return (10 + 20);

我見過一些老的微軟大佬寫的代碼里,return 是這么寫的:

return( 0);     // 括號(hào)直接頂著return

* ?? 舉個(gè)例子:庫(kù)函數(shù) src/strlen.c

size_t __cdecl strlen (
        const char * str
        )
{
        const char *eos = str;
 
        while( *eos++ ) ;
 
        return( eos - str - 1 );    ?? 表達(dá)式
}

0x06 深入淺出:Hello,World!

現(xiàn)在,我們已經(jīng)解釋完所有 Hello,World 的細(xì)節(jié)了,并且把其中的知識(shí)點(diǎn)都講的差不多了。

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃??現(xiàn)在我們?cè)倩氐阶畛醯钠瘘c(diǎn),再次感受那個(gè)跨越歷史的時(shí)刻……

#include <stdio.h>

int main(void)
{
	printf("Hello, World!\n");

	return 0;
}

經(jīng)過本章的學(xué)習(xí)后,你也應(yīng)該會(huì)有一個(gè)大概的認(rèn)識(shí)了。

我們通過這 Hello World 來(lái)展開了我們的教學(xué)專欄,介紹了頭文件、主函數(shù)和一些基礎(chǔ)概念。

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃??這樣的開篇方式我們構(gòu)思了很久很久,希望能得到大家的喜愛!

C 語(yǔ)言之父 丹尼斯里奇?的曾言:

" C 詭異離奇,缺陷重重,卻獲得了巨大的成功。"

C 語(yǔ)言無(wú)疑是改變?nèi)祟悮v史的最偉大發(fā)明之一……

在計(jì)算機(jī)蓬勃發(fā)展的今天,我們是站在了巨人的肩膀上,得以讓我們看得更高,行的更遠(yuǎn)……

學(xué)習(xí) C 語(yǔ)言的過程是漫長(zhǎng)且枯燥的,一定要有一個(gè)非常強(qiáng)大的心理狀態(tài)。

?? 翁凱老師說:在計(jì)算機(jī)里頭沒有任何黑魔法!

學(xué)計(jì)算機(jī)一定要有一個(gè)非常強(qiáng)大的心理狀態(tài),計(jì)算機(jī)的所有東西都是人做出來(lái)的,別人能想的出來(lái),我也一定能想得出來(lái),在計(jì)算機(jī)的世界里沒有任何的黑魔法,所有的東西只不過是我現(xiàn)在不知道而已,總有一天我會(huì)把所有的細(xì)節(jié)、所有的內(nèi)部的東西全搞明白的。

尾記:如何學(xué)習(xí)一門編程語(yǔ)言?

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?

我的編程母語(yǔ)是易語(yǔ)言(一款中文編程語(yǔ)言),我的編程啟蒙導(dǎo)師是覓風(fēng)。

覓風(fēng)老師在他的 《易語(yǔ)言視頻教程》中說過:

" 興趣是最好的老師。"

如果你對(duì)編程感興趣,那么這條路及時(shí)很艱難,你也會(huì)有無(wú)窮無(wú)盡的力量。

其次就是多動(dòng)手,代碼眼看千遍不如手敲一遍,多動(dòng)手去實(shí)操,畢竟:

" 紙上得來(lái)終覺淺,絕知此事要躬行。"

然后就是多看源碼,看看高手是怎么寫代碼的,大有裨益。

最后,遇到問題要深入了解,要具備對(duì)編程知識(shí)的求知欲,對(duì)問題要有鉆研精神。

c語(yǔ)言趣味教程,C語(yǔ)言趣味教程 - 入門到實(shí)戰(zhàn),C語(yǔ)言趣味教程 (試讀),c語(yǔ)言,頭文件,main函數(shù),原力計(jì)劃?

  • 網(wǎng)制焦,實(shí)不嚴(yán),沒畢業(yè),零經(jīng)驗(yàn),面八家,十offer,三萬(wàn)二,外包也,兩萬(wàn)七,自研也,明日有,多面試。說寒冬,年年有,計(jì)算機(jī),月過萬(wàn),現(xiàn)不學(xué),沒機(jī)會(huì),趁紅利,狠賺筆。
?? [ 筆者 ]? ?王亦優(yōu) | 雷向明
?? [ 更新 ]? ?2023.6.29(初稿)| 2023.7.1(審稿結(jié)束)
? [ 勘誤 ]?? /* 暫無(wú) */
?? [ 聲明 ]? ?由于作者水平有限,本文有錯(cuò)誤和不準(zhǔn)確之處在所難免,
              本人也很想知道這些錯(cuò)誤,懇望讀者批評(píng)指正!

?? 參考文獻(xiàn):文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-616739.html

  • - C++reference[EB/OL]. []. http://www.cplusplus.com/reference/.
  • - Microsoft. MSDN(Microsoft Developer Network)[EB/OL]. []. .
  • - 百度百科[EB/OL]. []. https://baike.baidu.com/.
  • - 維基百科[EB/OL]. []. https://zh.wikipedia.org/wiki/Wikipedia
  • - R. Neapolitan, Foundations of Algorithms (5th ed.), Jones & Bartlett, 2015.
  • - B. 比特科技. C/C++[EB/OL]. 2021[2021.8.31]
  • - 林銳博士. 《高質(zhì)量C/C++編程指南》[M]. 1.0. 電子工業(yè), 2001.7.24.
  • - 陳正沖. 《C語(yǔ)言深度解剖》[M]. 第三版. 北京航空航天大學(xué)出版社, 2019.
  • - 侯捷. 《STL源碼剖析》[M]. 華中科技大學(xué)出版社, 2002.
  • - T. Cormen《算法導(dǎo)論》(第三版),麻省理工學(xué)院出版社,2009年。
  • - T. Roughgarden, Algorithms Illuminated, Part 1~3, Soundlikeyourself Publishing, 2018.
  • - J. Kleinberg&E. Tardos, Algorithm Design, Addison Wesley, 2005.
  • - R. Sedgewick&K. Wayne,《算法》(第四版),Addison-Wesley,2011
  • - S. Dasgupta,《算法》,McGraw-Hill教育出版社,2006。
  • - S. Baase&A. Van Gelder, Computer Algorithms: 設(shè)計(jì)與分析簡(jiǎn)介》,Addison Wesley,2000。
  • - E. Horowitz,《C語(yǔ)言中的數(shù)據(jù)結(jié)構(gòu)基礎(chǔ)》,計(jì)算機(jī)科學(xué)出版社,1993
  • - S. Skiena, The Algorithm Design Manual (2nd ed.), Springer, 2008.
  • - A. Aho, J. Hopcroft, and J. Ullman, Design and Analysis of Algorithms, Addison-Wesley, 1974.
  • - M. Weiss, Data Structure and Algorithm Analysis in C (2nd ed.), Pearson, 1997.
  • -?A. Levitin, Introduction to the Design and Analysis of Algorithms, Addison Wesley, 2003. - A. Aho, J.?
  • - E. Horowitz, S. Sahni and S. Rajasekaran, Computer Algorithms/C++, Computer Science Press, 1997.
  • - R. Sedgewick, Algorithms in C: 第1-4部分(第三版),Addison-Wesley,1998
  • - R. Sedgewick,《C語(yǔ)言中的算法》。第5部分(第3版),Addison-Wesley,2002

到了這里,關(guān)于【C語(yǔ)言趣味教程】(1) 深入淺出 HelloWorld:通過 HelloWorld 展開教學(xué) | 頭文件詳解 | main 函數(shù)詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 深入淺出分支語(yǔ)句—【C語(yǔ)言】

    深入淺出分支語(yǔ)句—【C語(yǔ)言】

    目錄 前言:為什么要學(xué)習(xí)分支和循環(huán)語(yǔ)句呢? 1. 語(yǔ)句的分類 2. 分支語(yǔ)句(選擇語(yǔ)句) 2.1 if-else語(yǔ)句 注意點(diǎn):if-else語(yǔ)句后面不加{},默認(rèn)只能跟一條語(yǔ)句 2.2? switch語(yǔ)句 ?注意點(diǎn): 因?yàn)镃語(yǔ)言是一門結(jié)構(gòu)化的程序設(shè)計(jì)語(yǔ)言,具有三種結(jié)構(gòu):順序結(jié)構(gòu)、選擇結(jié)構(gòu)、循環(huán)結(jié)構(gòu),這三

    2024年02月02日
    瀏覽(161)
  • 深入淺出循環(huán)語(yǔ)句—【C語(yǔ)言】

    深入淺出循環(huán)語(yǔ)句—【C語(yǔ)言】

    ? 分支語(yǔ)句博客: http://t.csdn.cn/U2kZF 目錄 ?編輯 前言:我們先來(lái)了解一下break 、continue在循環(huán)中的作用 1. while循環(huán) ?while循環(huán)中的break ?while循環(huán)中的continue? 2. for循環(huán) for循環(huán)省略出錯(cuò)舉例: ?for循環(huán)中的break ?for循環(huán)中的continue 3. do???while循環(huán) 利用do?while循環(huán)打印1~10? ?d

    2024年02月04日
    瀏覽(231)
  • 深入淺出C語(yǔ)言—【函數(shù)】上

    深入淺出C語(yǔ)言—【函數(shù)】上

    ?? 目錄 1.函數(shù)的概念 2.C語(yǔ)言函數(shù)的分類 2.1 庫(kù)函數(shù) 2.1.1 strcpy庫(kù)函數(shù)舉例學(xué)習(xí)方式 2.1.2?庫(kù)函數(shù)擴(kuò)展知識(shí) 2.2 自定義函數(shù) 2.2.1求兩個(gè)整數(shù)中的較大值 3. 函數(shù)的參數(shù) 3.1 實(shí)際參數(shù)(實(shí)參) 3.2 形式參數(shù)(形參) 4. 函數(shù)的調(diào)用 4.1 傳值調(diào)用 4.2 傳址調(diào)用 老鐵們,網(wǎng)址自取,記得一鍵

    2024年02月07日
    瀏覽(82)
  • 深入淺出C語(yǔ)言—【函數(shù)】下

    深入淺出C語(yǔ)言—【函數(shù)】下

    函數(shù)和函數(shù)之間可以根據(jù)實(shí)際的需求進(jìn)行組合的,也就是互相調(diào)用的。 注意: 函數(shù)可以嵌套調(diào)用,但是不能嵌套定義。 把一個(gè)函數(shù)的返回值作為另外一個(gè)函數(shù)的參數(shù)。 上面的strlen函數(shù)是求數(shù)組長(zhǎng)度的庫(kù)函數(shù), 特別注意的是,當(dāng)數(shù)組為字符數(shù)組時(shí),數(shù)組的末尾會(huì)自動(dòng)放一個(gè)

    2024年02月17日
    瀏覽(114)
  • 深入淺出:大語(yǔ)言模型的視覺解析

    深入淺出:大語(yǔ)言模型的視覺解析

    一系列工具與文章的匯編,直觀易懂地解讀復(fù)雜的 AI 概念 圖片由作者利用 unDraw.co 的免費(fèi)插圖制作 在當(dāng)今世界,大語(yǔ)言模型(LLM)成為了熱門話題。幾乎每天都有新的語(yǔ)言模型問世,讓人們?cè)?AI 領(lǐng)域懷有一種“不容錯(cuò)過”的緊迫感。盡管如此,許多人仍對(duì)大語(yǔ)言模型的基礎(chǔ)

    2024年01月19日
    瀏覽(25)
  • 深入淺出對(duì)話系統(tǒng)——自然語(yǔ)言理解模塊

    深入淺出對(duì)話系統(tǒng)——自然語(yǔ)言理解模塊

    首先回顧一下自然語(yǔ)言理解的概念。 自然語(yǔ)言理解(Natural Language Understanding)包含三個(gè)子模塊: 其中領(lǐng)域識(shí)別和意圖識(shí)別都是分類問題,而語(yǔ)義槽填充屬于序列標(biāo)注問題。所以,在自然語(yǔ)言理解中,我們要解決兩個(gè)分類任務(wù)和一個(gè)序列標(biāo)注任務(wù)。既然其中兩個(gè)問題都屬于分類任

    2024年02月08日
    瀏覽(21)
  • 深入淺出堆—C語(yǔ)言版【數(shù)據(jù)結(jié)構(gòu)】

    深入淺出堆—C語(yǔ)言版【數(shù)據(jù)結(jié)構(gòu)】

    二叉樹概念博客 :http://t.csdn.cn/XIW84 目錄 1. 了解堆 1.1 堆的概念 1.2 堆的性質(zhì): 1.3 堆的結(jié)構(gòu)圖片 1.3.1 小堆 1.3.2 大堆 2. 堆的實(shí)現(xiàn) 2.1 插入數(shù)據(jù)進(jìn)堆 2.2 向上調(diào)整函數(shù) 2.3 堆的刪除 2.4 向下調(diào)整 3. 堆的應(yīng)用 3.1 建堆(兩種方式) 3.1.1 建堆方式1 3.1.2 建堆方式2 3.2 堆排序? 3.3 堆的

    2024年02月04日
    瀏覽(24)
  • 深入淺出二叉樹— C語(yǔ)言版【數(shù)據(jù)結(jié)構(gòu)】

    深入淺出二叉樹— C語(yǔ)言版【數(shù)據(jù)結(jié)構(gòu)】

    目錄 ?編輯 1.樹概念及結(jié)構(gòu) 1.1樹的概念 1.2 樹的相關(guān)概念 ?1.3 樹的表示 2.二叉樹概念及結(jié)構(gòu)? ?2.1概念 2.2 特殊的二叉樹 2.3 二叉樹的性質(zhì)? 2.4 簡(jiǎn)單二叉樹題目練習(xí)? 2.5 二叉樹的存儲(chǔ)結(jié)構(gòu) 2.5.1 順序存儲(chǔ)——堆 2.5.2 鏈?zhǔn)酱鎯?chǔ) 樹是一種 非線性的數(shù)據(jù)結(jié)構(gòu) ,它是由n(n=0)個(gè)有

    2024年02月03日
    瀏覽(20)
  • 深入淺出對(duì)話系統(tǒng)——基于預(yù)訓(xùn)練語(yǔ)言模型的對(duì)話管理

    深入淺出對(duì)話系統(tǒng)——基于預(yù)訓(xùn)練語(yǔ)言模型的對(duì)話管理

    主要講解三篇論文,主要思想是把自然語(yǔ)言理解、對(duì)話管理和自然語(yǔ)言生成三部分整合到一起。 數(shù)據(jù)集 CamRest676 MultiWOZ 都是用的自回歸語(yǔ)言模型 causal GPT-2、Transformer Decoder 一個(gè)概念:delexicalization 通過相應(yīng)的占位符替換特定的槽值 占位符作為特定的token,不關(guān)心具體的取值

    2024年02月16日
    瀏覽(163)
  • Git入門圖文教程(深入淺出,詳細(xì)了解Git,以及操作)

    Git入門圖文教程(深入淺出,詳細(xì)了解Git,以及操作)

    Git是當(dāng)前最先進(jìn)、最主流的 分布式 版本控制系統(tǒng),免費(fèi)、開源!核心能力就是版本控制。再具體一點(diǎn),就是面向代碼文件的版本控制,代碼的任何修改歷史都會(huì)被記錄管理起來(lái),意味著可以恢復(fù)到到以前的任意時(shí)刻狀態(tài)。支持跨區(qū)域多人協(xié)作編輯,是團(tuán)隊(duì)項(xiàng)目開發(fā)的必備基

    2024年02月08日
    瀏覽(19)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包