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

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

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

?c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?? 《C語言趣味教程》?? 猛戳訂閱!?。?/strong>


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

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

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

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

—— 沃茲基碩德

?? 本章目錄:

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

0x00 引入:HelloWorld 的由來

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

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

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

Ⅱ. 頭文件(Header)

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

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

0x02 引入頭文件的方式

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

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

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

* 0x06?實踐錯誤記錄:#include 展開的問題

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

* 0x08 整理:stdio 定義的庫變量、庫宏和庫函數(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?頗有爭議的寫法:void main()

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

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

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

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

Ⅳ. 深入淺出:Hello,World!

0x00 引入:再看 Hello,World!

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

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

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

0x04 返回語句 return?

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

0x06 深入淺出:Hello,World!

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


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

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

0x00 引入:HelloWorld 的由來

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃

?? 思考:什么是 Hello World ?它又是怎么來的?

Hello World 是一種常見的計算機程序,通常作為一個新編程語言或平臺的入門示例。

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃??它的起源可以追溯到 1974 年,由計算機科學(xué)家?布萊恩·柯林漢?創(chuàng)造。

沒錯,就是那個?80 歲還在咔咔咔寫代碼的巨佬,貝爾實驗室的 神仙?!

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃??在?C 語言第一本教材《C程序設(shè)計語言》中,

他使用了 Hello World 作為一個簡單的示例,來介紹 C 語言的基本語法。

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃??同時,他還是開發(fā) Unix 的主要貢獻者,Unix 就是由柯林漢命名的!

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃??可以這么說,當(dāng)你把 Hello World 這幾個字成功打印到屏幕上時,

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

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

Hello World 究竟從何而來?

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃

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

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

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

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

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃??下面我先打開我的編輯器,我的代碼編輯器是:

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃??大人!時代變了!怎么還有人在用 VC6.0???!不會吧?

哈哈哈哈哈,怎么會!我用的可是支持腦機接口編程的?VS2077?:

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?

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

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?

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

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?

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

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


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

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

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

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

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

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

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

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?(簡約而不失優(yōu)雅的加載頁面...)

?進入下方頁面后,點擊右下角的?創(chuàng)建新項目 (N)

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?

?然后點擊?空項目

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?名稱我們就取為 test.c,然后點 添加(A),我們的工程就會在指定的位置很好地創(chuàng)建出來:

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃??這里的 .c 文件 和 .h 以及 VS 默認(rèn)的 .cpp 后綴是什么?我們來簡單介紹一下:

簡而言之,.c?文件用于 C 語言編程,.cpp?文件用于 C++ 編程:

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

(這些我們在后期講解 編譯鏈接 時都會詳細(xì)講解,這里只需要 .c 是 C 語言源文件的后綴即可)

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?創(chuàng)建完畢后,我們就可以在 test.c?下打代碼了:

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?

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

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃??如果你是一個初學(xué)者,我們很能理解你迫切的想要敲出 Hello,World 的心情!

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?

" 手動播放勁爆的新寶島 bgm,敲下這令人激動的第一個代碼!"

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

#include <stdio.h>

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

	return 0;
}

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

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃??當(dāng)然你也可以使用快捷鍵運行,輸入?Ctrl + F5?運行代碼:

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?

我們也推薦大家使用!因為作為鍵盤俠,使用快捷鍵會很 cool !

運行后就會彈出一個窗口 ——?Microsoft Visual Stidio?調(diào)試控制臺:

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?

我們可以看到,我們的 Hello, World! 在控制臺上出現(xiàn)了,這是因為我們調(diào)用了打印函數(shù) printf

#include <stdio.h>

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

	return 0;
}

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃??只會敲 Hello World 的我瑟瑟發(fā)抖……

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?下面我們會慢慢地、深入淺出地講解剛才的 Hello World 代碼:

#include <stdio.h>

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

	return 0;
}

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃??等講解完這些必要的知識點后,我們再回來看這段代碼,就會非常地清楚 ~

Ⅱ. 頭文件(Header)

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

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?下面是 HelloWorld 示例程序的第一行代碼:

#include <stdio.h>    // 引入頭文件 stdio 庫

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

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?

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

后綴為 .h 的文件被稱為 "頭文件" ,因為頭文件的英文是 header,所以縮寫為 .h

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

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

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


在 C 語言中,頭文件是一個文件。頭文件通常是源代碼的形式,由編譯器在處理另一個源文件時自動包含進來。程序員通過編譯器指令將頭文件包含進其他源文件的開始。

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

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

我們使用 #include 來引用頭文件,這是一個 C 預(yù)處理指令,對于預(yù)處理的知識我們后期會講解。

#include         引入頭文件

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃??這是什么?下面,我們就來介紹一下這個 stdio.h。

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

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

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?

因為我們的 HelloWorld 示例程序需要用到 printf 這個函數(shù),所以我們需要引入 stdio.h !

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃??之所以叫做 stdio 是因為?standard input & output,而它表示了這庫中最經(jīng)典的兩個函數(shù):

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

(對于這兩個函數(shù),我們后續(xù)會詳細(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語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃??我們前面講了,我們使用 #include 來引用頭文件,這個 # 是預(yù)處理指令。

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

剛才我們介紹了 stdio.h 庫,現(xiàn)在我們再來觀察?HelloWorld 示例程序的第一行代碼:

#include <stdio.h>

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃??我們可以看到 #include 后面使用了兩個尖括號 < > 包住了 stdio.h

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

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

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?首先,< >" " 包含頭文件的本質(zhì)區(qū)別是查找策略區(qū)別。

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

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

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

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

? 思考:那可不可以用雙引號 " " 包含庫文件?

#include "stdio.h"

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃??當(dāng)然,庫文件也是可以使用 " " 包含的,但是不建議庫文件用 " " 形式引入!

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

但是這樣查找的效率就會大打折扣,因為會先從源文件所在目錄下去找一遍,然后再去找。

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?而且這樣也不容易區(qū)分是庫文件還是本地文件。

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

① 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語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?要做到聲明與定義相分離,頭文件中應(yīng)當(dāng)只存放聲明,而不存放定義。

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

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

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

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

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

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

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃??比如下面這個代碼,仔細(xì)觀察你會發(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ù)引用錯誤,此時編譯器會處理兩次頭文件的內(nèi)容,從而產(chǎn)生錯誤。

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

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

#ifndef STDIO_H
#define STDIO_H

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

#endif

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

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

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃??該技術(shù)我們稱之為 頭文件保護 (header guards) ,可以有效確保頭文件只被包含一次。

? 如果嫌麻煩,還有一種非常簡單的方法:

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

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

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

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?條件引用是一種根據(jù)特定條件來選擇性包含或排除代碼的技術(shù)。

如果需要從多個不同的頭文件選擇一個引用到程序中,此時就需要用?"有條件引用" 來達成目的。

舉個例子,現(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)頭文件較多時,此這么做顯然不妥,我們可以預(yù)處理器使用宏來定義頭文件的名稱。

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

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

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

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

* 0x06?實踐錯誤記錄:#include 展開的問題

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃??#include 的展開是有特點的,下面我將通過一個實踐中碰到的例子,來講解展開的特點。

?? 舉個例子:下面我們手動定義了一顆二叉樹(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é)點 */
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;
}

/* 手動創(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語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?所以我們需要修改一下 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);                    //隊列初始化
void QueueDestroy(Queue* pQ);                 //銷毀隊列
bool QueueIfEmpty(Queue* pQ);                 //判斷隊列是否為空
void QueuePush(Queue* pQ, QueueDataType x);   //入隊
void QueuePop(Queue* pQ);                     //出隊
QueueDataType QueueFront(Queue* pQ);          //返回隊頭數(shù)據(jù)
QueueDataType QueueBack(Queue* pQ);           //返回隊尾數(shù)據(jù)
int QueueSize(Queue* pQ);                     //求隊列大小

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?此時令人瞠目結(jié)舌的問題就出現(xiàn)了,我們運行代碼就會產(chǎn)生報錯:

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?我們來冷靜分析一下這個報錯,分析完你會發(fā)現(xiàn)分析了個寂寞……

報錯說又缺少 " { " 又缺少 " ) "?的,這明顯是胡說八道。

我們的編譯器在這里就顯得沒有這么智能了,報的錯都開始胡言亂語了。

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

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

就需要 "往上面" 去找這個類型。這里顯然往上找,是找不到它的定義的,所以編譯器會報錯。

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?

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

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

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

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

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃??那我們該怎么做,才能徹底解決呢??

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?

?? 代碼演示:使用 "前置聲明" 修改后的 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);                    //隊列初始化
void QueueDestroy(Queue* pQ);                 //銷毀隊列
bool QueueIfEmpty(Queue* pQ);                 //判斷隊列是否為空
void QueuePush(Queue* pQ, QueueDataType x);   //入隊
void QueuePop(Queue* pQ);                     //出隊
QueueDataType QueueFront(Queue* pQ);          //返回隊頭數(shù)據(jù)
QueueDataType QueueBack(Queue* pQ);           //返回隊尾數(shù)據(jù)
int QueueSize(Queue* pQ);                     //求隊列大小

此時問題就解決了,頭文件展開后不會引發(fā)報錯問題。

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

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?如果一個工程中有大量的 .h 文件 和 .c 文件,此時難免會很亂。

此時我們可以選擇用一個 global.h 的頭文件來把所有?.h 文件 "打包" 起來,

在除 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 定義的庫變量、庫宏和庫函數(shù)

?? 專欄閱讀貼士

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

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

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

庫變量 (Library Variable):

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

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

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

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ù)時會詳細(xì)講解。

4. FOPEN_MAX

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

5. FILENAME_MAX

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

6. L_tmpnam

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

7. _IOFBF
8. _IOLBF
9. _IONBF

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

10. SEEK_CUR
11. SEEK_END
12. SEEK_SET

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

13. TMP_MAX

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

14. stderr
15. stdin
16. stdout

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

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

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

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

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃??剛才我們講解了 #include <stdio.h>,下面我們來看第三行代碼,int main()?

#include <stdio.h>

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

	return 0;
}

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

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

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

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

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

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

#include <stdio.h>

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

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

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

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?

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

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

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?main 函數(shù)的返回類型取決于 main 標(biāo)識符前是什么數(shù)據(jù)類型,比如這里是 int:

int main() 
{
    return 0;
}

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

在我們的演示代碼 HelloWorld 中,我們可以看到,main 后面跟了一個括號,

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃??我們可以在括號里面加上一個 void,就像這樣:

int main(void)

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

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

#include <stdio.h>        

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

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

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?下面我先列舉一些大家常見的主函數(shù)形式,然后我們再慢慢評價。

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

int main()
int main(void)

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

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[])

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

main()

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

直接報錯型(相信 90% 的程序員都犯過這個錯誤):

int mian()

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

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃??我們平時寫 main 函數(shù)的時 main 函數(shù)參數(shù)一般都不寫,即括號里什么都不填。

或者填上一個 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ù)就會報錯,程序必須要有返回值。

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

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

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

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

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

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

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

argv?是一個指向字符指針數(shù)組的指針,用于存儲命令行參數(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("第一個參數(shù)(程序名稱):%s\n", argv[0]);

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

    return 0;
}

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃??首先拋出一個事實 —— C/C++ 中從來沒有定義過 void main()

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

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

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

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

void main()
void main(void)

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?光從語法角度上來看,C 語言里是可以編譯運行 void main 的。

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

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

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

很多人說這種寫法都是 "譚C" 帶的,事實上并非如此,因為早在上世紀(jì)就已然出現(xiàn)了這種寫法。

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

—— 電腦博物館站長

?c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃??當(dāng)然,一些編譯器?void main 是可通過編譯的,比如 VC6.0?

有人說 void main 其實挺合理的,編寫單片機的話你 return 給值給誰?

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?此時出現(xiàn)了一個非常炸裂的回答:你可以不收,我不能不給。

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

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

?? 鏈接:C 語言的「void main」是怎么一代代傳下來的? - 知乎

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?C89 標(biāo)準(zhǔn)中支持這種只丟一個 main() 的寫法:

main()

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

你看到有人直接扔一個?main() 但是不報錯,事實上也只是編輯器支持而已。

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

" 因為真的很有趣,所以我不得不提一提。"

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?相信很多人都犯過這個錯誤,不小心把 main 打成了?mian……

int mian(void)    

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?

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

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

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃??可以保障代碼的通用性和可移植性,沒有 bug,豈不美哉?

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

待更新……

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

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

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?

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

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

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

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

#include <stdio.h>

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

	return 0;
}

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?

Ⅳ. 深入淺出:Hello,World!

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

0x00 引入:再看 Hello,World!

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

#include <stdio.h>

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

	return 0;
}

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃??我們剛才講解了頭文件和 main 函數(shù),

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

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

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

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

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

函數(shù)體是用花括號括起來的若干語句,他們完成了一個函數(shù)的具體功能。

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

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

#include <stdio.h>

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

	return 0;
}

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?一對花括號?{ } 由 左花括號 {? 和 右花括號 } 組成,左花括號匹配右花括號。

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?

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

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

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

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

雙引號內(nèi)的內(nèi)容可以輸出到 控制臺,所以我們的 Hello,World 示例程序運行后控制臺會顯示:

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?

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

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

? 這里的 \n 為什么沒有被打印出來?

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

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

?c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃??在我們?nèi)粘I钪校?"句號" 表示一段話的結(jié)束。

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

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

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

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?

不加分號會報錯,人難免是會忘的,如果忘記加了編譯器會提示:

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?

隨著敲代碼越來越熟練,忘記加分號的情況會越來越少的,就像你寫作文不會忘記加句號一樣。

遺漏分號會引發(fā) C2143 號報錯:error C2143: 語法錯誤: 缺少“;”?

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

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?

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

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

0x04 返回語句 return?

我們前面說了,因為我們的 main 函數(shù)的返回值類型定義的是 int,所以我們需要 return 一個值:

#include <stdio.h>

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

	return 0;
}

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

return 返回值;

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

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

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

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

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

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

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

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

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

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

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

0x06 深入淺出:Hello,World!

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃??現(xiàn)在我們再回到最初的起點,再次感受那個跨越歷史的時刻……

#include <stdio.h>

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

	return 0;
}

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

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃??這樣的開篇方式我們構(gòu)思了很久很久,希望能得到大家的喜愛!

C 語言之父 丹尼斯里奇?的曾言:

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

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

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

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

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

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

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?

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

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

" 興趣是最好的老師。"

如果你對編程感興趣,那么這條路及時很艱難,你也會有無窮無盡的力量。

其次就是多動手,代碼眼看千遍不如手敲一遍,多動手去實操,畢竟:

" 紙上得來終覺淺,絕知此事要躬行。"

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

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

c語言趣味教程,C語言趣味教程,c語言,頭文件,main函數(shù),原力計劃?

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

?? 參考文獻:文章來源地址http://www.zghlxwxcb.cn/news/detail-609937.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語言深度解剖》[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è)計與分析簡介》,Addison Wesley,2000。
  • - E. Horowitz,《C語言中的數(shù)據(jù)結(jié)構(gòu)基礎(chǔ)》,計算機科學(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語言中的算法》。第5部分(第3版),Addison-Wesley,2002

到了這里,關(guān)于【C語言趣味教程】(1) 深入淺出 HelloWorld:夢開始的地方!通過 HelloWorld 展開教學(xué) | 頭文件詳解 | main 函數(shù)詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

  • 深入淺出Python:從零開始搭建自己的Web服務(wù)器

    第一部分:前言與環(huán)境準(zhǔn)備 1. 前言 隨著互聯(lián)網(wǎng)的發(fā)展,越來越多的應(yīng)用都運行在Web上,而Web服務(wù)器則成為了支撐這一切的關(guān)鍵。在本文中,我們將利用Python來創(chuàng)建自己的簡易Web服務(wù)器。通過這個過程,你不僅可以深入了解Web服務(wù)器的工作原理,還能夠掌握Python的基礎(chǔ)知識。

    2024年02月03日
    瀏覽(92)
  • 深入淺出分支語句—【C語言】

    深入淺出分支語句—【C語言】

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

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

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

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

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

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

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

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

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

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

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

    深入淺出:大語言模型的視覺解析

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

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

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

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

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

    深入淺出堆—C語言版【數(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. 堆的實現(xiàn) 2.1 插入數(shù)據(jù)進堆 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日
    瀏覽(25)
  • 深入淺出二叉樹— C語言版【數(shù)據(jù)結(jié)構(gòu)】

    深入淺出二叉樹— C語言版【數(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 簡單二叉樹題目練習(xí)? 2.5 二叉樹的存儲結(jié)構(gòu) 2.5.1 順序存儲——堆 2.5.2 鏈?zhǔn)酱鎯?樹是一種 非線性的數(shù)據(jù)結(jié)構(gòu) ,它是由n(n=0)個有

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

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

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

    2024年02月16日
    瀏覽(163)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包