??? 《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 的由來
"所有的偉大,都源于一個勇敢的開始!"
?? 思考:什么是 Hello World ?它又是怎么來的?
Hello World 是一種常見的計算機程序,通常作為一個新編程語言或平臺的入門示例。
??它的起源可以追溯到 1974 年,由計算機科學(xué)家?布萊恩·柯林漢?創(chuàng)造。
沒錯,就是那個?80 歲還在咔咔咔寫代碼的巨佬,貝爾實驗室的 神仙?!
??在?C 語言第一本教材《C程序設(shè)計語言》中,
他使用了 Hello World 作為一個簡單的示例,來介紹 C 語言的基本語法。
他與?C 語言之父 ——?丹尼斯里奇?共同合作了撰寫了這本書,K&R?就是兩人名字的縮寫。
?
??同時,他還是開發(fā) Unix 的主要貢獻者,Unix 就是由柯林漢命名的!
"全員惡人?什么惡人?全員神仙!"
?
??可以這么說,當(dāng)你把 Hello World 這幾個字成功打印到屏幕上時,
你的內(nèi)心體驗到的不僅僅是一種成功的喜悅,更重要的是,你正在親身經(jīng)歷一個跨越歷史的時刻!
" 編程生涯,由此開始!"
Hello World 究竟從何而來?
當(dāng) Forbes India 雜志采訪柯林漢時,他本人對自己這段傳奇故事中一些記憶已經(jīng)有點兒模糊了。當(dāng)被問及為什么選擇 "Hello, World! "時,他回答道:"我只記得,我好像看過一幅漫畫,講述一枚雞蛋和一只小雞的故事,在那副漫畫中,小雞說了一句 Hello World " ——
0x01 代碼編輯器的選用(推薦 VS2022)
??剛才我們了解了 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 等。
??下面我先打開我的編輯器,我的代碼編輯器是:
?
??大人!時代變了!怎么還有人在用 VC6.0???!不會吧?
哈哈哈哈哈,怎么會!我用的可是支持腦機接口編程的?VS2077?:
?
開個玩笑,其實是 VS2022!本系列博客 Windows 系統(tǒng)下一律選用 Visual Studio 2022?。
我們也是非常推薦大家使用 VS2022 的,臣以為 VS2022 真乃 「宇宙最強編輯器」 也!
?
" 強烈建議安裝,用過都說好,下載鏈接我貼到下面了。"
?? VS 官網(wǎng):Visual Studio 2022 IDE - 適用于軟件開發(fā)人員的編程工具
?
學(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 的安裝教程的。
?下面,我們將認(rèn)為讀者已經(jīng)安裝好了 VS2022,并帶著大家手把手敲出 Hello,World!
?? 注意:所以為了更好地貼合本專欄進行系統(tǒng)性地學(xué)習(xí),盡量選用?Visual Studio?!
0x02 創(chuàng)建新項目
①?首先,找到桌面快捷方式,雙擊打開?Visual Studio 2022:
?(簡約而不失優(yōu)雅的加載頁面...)
②?進入下方頁面后,點擊右下角的?創(chuàng)建新項目 (N) :
?
③?然后點擊?空項目:
?
④ 隨后到了配置新項目,這里創(chuàng)建項目名稱,演示階段名字自行取,之后點擊 創(chuàng)建 (C)?:
?
⑤ 創(chuàng)建完新項目后,我們找到 解決方案資源管理器,右鍵 "源文件",點擊 "添加新建項" :
?
?名稱我們就取為 test.c,然后點 添加(A),我們的工程就會在指定的位置很好地創(chuàng)建出來:
?
??這里的 .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 語言源文件的后綴即可)
?創(chuàng)建完畢后,我們就可以在 test.c?下打代碼了:
?
??至此,我們要做的準(zhǔn)備工作基本就完成了,下面我們就要開始敲 Hello,World 了!
0x03?敲下這 “跨越歷史” 的 Hello World!
??如果你是一個初學(xué)者,我們很能理解你迫切的想要敲出 Hello,World 的心情!
我們現(xiàn)在就拉出本教程的第一個代碼 —— Hello,World,來讓大家 一睹芳容 !
?
" 手動播放勁爆的新寶島 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)試)? :
?
??當(dāng)然你也可以使用快捷鍵運行,輸入?Ctrl + F5?運行代碼:
?
我們也推薦大家使用!因為作為鍵盤俠,使用快捷鍵會很 cool !
運行后就會彈出一個窗口 ——?Microsoft Visual Stidio?調(diào)試控制臺:
?
我們可以看到,我們的 Hello, World! 在控制臺上出現(xiàn)了,這是因為我們調(diào)用了打印函數(shù) printf :
#include <stdio.h>
int main()
{
printf("Hello, World!\n"); ?? 打印 Hello,World
return 0;
}
(如果是零基礎(chǔ)讀者,看不明白這段代碼,這都沒有關(guān)系,我們會深入淺出地慢慢講解)
??只會敲 Hello World 的我瑟瑟發(fā)抖……
至此,我們的 Hello World 就敲完了,我們也成功的將這段話輸出到了我們的顯示器上。
?下面我們會慢慢地、深入淺出地講解剛才的 Hello World 代碼:
#include <stdio.h>
int main()
{
printf("Hello, World!\n");
return 0;
}
??等講解完這些必要的知識點后,我們再回來看這段代碼,就會非常地清楚 ~
Ⅱ. 頭文件(Header)
- 圍繞著 HelloWorld 繼續(xù)推進,理解第一行代碼我們需要先知道什么是頭文件,以及我們引入的 stdio 庫,這里我們會詳細(xì)的講解各種頭文件的知識點,包含了頭文件保護、聲明定義分離、#include 展開等內(nèi)容。
0x00?引入:什么是頭文件?
?下面是 HelloWorld 示例程序的第一行代碼:
#include <stdio.h> // 引入頭文件 stdio 庫
* 注:兩個斜杠 (?//?) 后面的內(nèi)容屬于「注釋」,我們會在下一章進行講解!
這一行代碼的意思是 "引入頭文件 stdio.h 庫",我們先來簡單介紹一下什么是 頭文件?(header)。
?
?? 概念:頭文件,?[英] 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?。
??這是什么?下面,我們就來介紹一下這個 stdio.h。
0x01?標(biāo)準(zhǔn)輸入輸出庫 stdio
stdio.h 是編譯器自帶的頭文件,其中 .h 我們剛才說過,是擴展名,被稱之為頭文件。
stdio 全稱 standard input & output,即標(biāo)準(zhǔn)輸入輸出,我們稱之為 C 標(biāo)準(zhǔn)庫,直接看圖記憶:
?
因為我們的 HelloWorld 示例程序需要用到 printf 這個函數(shù),所以我們需要引入 stdio.h !
??之所以叫做 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 引入頭文件的方式
??我們前面講了,我們使用 #include 來引用頭文件,這個 # 是預(yù)處理指令。
預(yù)處理指令 # 可用于宏定義、文件包含 和 條件編譯。
剛才我們介紹了 stdio.h 庫,現(xiàn)在我們再來觀察?HelloWorld 示例程序的第一行代碼:
#include <stdio.h>
??我們可以看到 #include 后面使用了兩個尖括號 < > 包住了 stdio.h。
尖括號中引入的頭文件基本都是 C 語言中各種各樣的?庫函數(shù),剛才學(xué)習(xí)的 stdio 就是其中之一。
這行代碼中,我們通過 #include <> 去引入了標(biāo)準(zhǔn)輸入輸出庫 stdio。
頭文件的引入除了尖括號 < > ,還有雙引號 " " 形式的引入:
?
?? 兩種引用方式的區(qū)別:頭文件用 < > 引入和用 " " 引入的區(qū)別
?首先,< > 和 " " 包含頭文件的本質(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"
??當(dāng)然,庫文件也是可以使用 " " 包含的,但是不建議庫文件用 " " 形式引入!
#include <stdio.h> 是庫文件,你用引號形式引入 #include "stdio.h" 也是可以的,
但是這樣查找的效率就會大打折扣,因為會先從源文件所在目錄下去找一遍,然后再去找。
我們既然明確知道自己是要使用庫文件了,我們自然就直接使用尖括號才是正常的。
?而且這樣也不容易區(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í)慣
?要做到聲明與定義相分離,頭文件中應(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ù)引用的失誤。
??比如下面這個代碼,仔細(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ù)處理器會跳過文件的整個類容,編譯器就會將其忽略不計。
??該技術(shù)我們稱之為 頭文件保護 (header guards) ,可以有效確保頭文件只被包含一次。
? 如果嫌麻煩,還有一種非常簡單的方法:
#pragma once // 讓頭文件即使被包含多次,也只包含一份
(具體的講解我們會在后面的預(yù)處理章節(jié)進行更加深刻細(xì)致的講解)
因此,為了預(yù)防頭文件被重復(fù)引入,建議使用 ifndef / define /?endif 結(jié)構(gòu)產(chǎn)生與處理塊。
* 0x05 條件引用技術(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 展開的問題
??#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,
?所以我們需要修改一下 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); //求隊列大小
?此時令人瞠目結(jié)舌的問題就出現(xiàn)了,我們運行代碼就會產(chǎn)生報錯:
?
?我們來冷靜分析一下這個報錯,分析完你會發(fā)現(xiàn)分析了個寂寞……
報錯說又缺少 " { " 又缺少 " ) "?的,這明顯是胡說八道。
我們的編譯器在這里就顯得沒有這么智能了,報的錯都開始胡言亂語了。
? 思考:這里產(chǎn)生問題的原因是什么呢?(提示:想想編譯器的原則)
?? 編譯器原則:編譯器認(rèn)識 int,是因為 int 是一個內(nèi)置類型。但是 BTNode* 編譯器并不認(rèn)識,
就需要 "往上面" 去找這個類型。這里顯然往上找,是找不到它的定義的,所以編譯器會報錯。
?
如果你要用這個類型,你就需要先定義這個類型。
test.c 文件中 #include "Queue.h" ,相當(dāng)于把這里的代碼拷貝過去了。
此時,由于 BTNode* 會在上面展開,導(dǎo)致找不到 BTNode*? 。
? 思考:我把 #include 移到 定義類型的代碼 的后面,可以解決問題嗎?
可以!遺憾的是只能解決這里 typedef BTNode* 的問題,還有 Queue.c 里的問題……
??那我們該怎么做,才能徹底解決呢??
?? 解決方案:使用前置聲明。這樣就不會帶來問題了,滿足了先聲明后使用。
?
?? 代碼演示:使用 "前置聲明" 修改后的 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 來管理頭文件
"有效避免頭文件過多,亂七八糟,不方便管理的問題。"
?如果一個工程中有大量的 .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 示例
??剛才我們講解了 #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ù),就像山東不能沒有曹縣!"
?
?? 鐵律:main函數(shù)是程序的入口,主函數(shù)有且僅有一個!
一個 C 語言程序的執(zhí)行,從 main 函數(shù)開始,到 main 函數(shù)結(jié)束。 如何理解呢?
你可以把 main 函數(shù)想象成入口,一切都從這里開始執(zhí)行,最后肯定也是要從這出去的。
?main 函數(shù)的返回類型取決于 main 標(biāo)識符前是什么數(shù)據(jù)類型,比如這里是 int:
int main()
{
return 0;
}
那么該主函數(shù)就存在一個整型類型的返回值,我們需要使用 return?去返回(我們后續(xù)再說)。
在我們的演示代碼 HelloWorld 中,我們可以看到,main 后面跟了一個括號,
括號中定義了函數(shù)的參數(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ù)的位置可以任意。
?下面我先列舉一些大家常見的主函數(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)在最普遍的寫法了。"
??我們平時寫 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)寫法 "
?該寫法也是? 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++ 中從來沒有定義過 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 語言里是可以編譯運行 void main 的。
因為 C 中的函數(shù)只關(guān)注函數(shù)名,而關(guān)注其返回類型,在找入口函數(shù)時僅僅在找 "main" 而已。
從匯編角度來看,返回值即函數(shù)返回時寄存器? 的值,因此 ?中總是有值的。
和變量一樣,不主動賦值給的是隨機數(shù),因此?void main 即使返回類型是 void,也是有返回值的。
很多人說這種寫法都是 "譚C" 帶的,事實上并非如此,因為早在上世紀(jì)就已然出現(xiàn)了這種寫法。
"還有甩鍋給譚C的,更是無稽之談,難道微軟和 Borland 的工程師也是跟譚C學(xué)的?"
—— 電腦博物館站長
???當(dāng)然,一些編譯器?void main 是可通過編譯的,比如 VC6.0?
有人說 void main 其實挺合理的,編寫單片機的話你 return 給值給誰?
?此時出現(xiàn)了一個非常炸裂的回答:你可以不收,我不能不給。
哈哈哈哈,看來寫代碼也講人情世故!return 什么無所謂,我就是要個態(tài)度 ~?
最后,對 void main 感興趣的朋友可以看此帖:
?? 鏈接:C 語言的「void main」是怎么一代代傳下來的? - 知乎
* 0x05?存在于 C89 的寫法:main()
?C89 標(biāo)準(zhǔn)中支持這種只丟一個 main() 的寫法:
main()
C?語言中是調(diào)用者負(fù)責(zé)清棧任務(wù),因此 main 函數(shù)不寫返回參數(shù)依然是可以的。
你看到有人直接扔一個?main() 但是不報錯,事實上也只是編輯器支持而已。
* 0x06?錯誤寫法:mian()
" 因為真的很有趣,所以我不得不提一提。"
?相信很多人都犯過這個錯誤,不小心把 main 打成了?mian……
int mian(void)
相信很多程序員在職業(yè)生涯中都犯過這個錯誤,看了半天沒看出問題到底出在哪里:
?
編譯器只會去找 main,你不小心寫成 mian 編譯器會說沒找到 main 函數(shù)的。
?? 總結(jié):我們只需老老實實地遵循 C 語言標(biāo)準(zhǔn)文檔的兩種寫法,就行了。
int main(void) { /* ... */ }
int main(int argc, char *argv[]) { /* ... */ }
??可以保障代碼的通用性和可移植性,沒有 bug,豈不美哉?
* 0x07?main 函數(shù)執(zhí)行前做的事
待更新……
* 0x08 可以調(diào)用 main 函數(shù)嗎?
?? 思考:用戶可不可以調(diào)用 main 函數(shù)?
這個問題乍一看會讓人覺得,不可以吧……main 函數(shù)怎么可以讓用戶調(diào)呢:?
?
很多人都沒有想過這個問題,但事實上是可以的,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é)果如下:
?
Ⅳ. 深入淺出: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;
}
??我們剛才講解了頭文件和 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;
}
?一對花括號?{ } 由 左花括號 {? 和 右花括號 } 組成,左花括號匹配右花括號。
比如這里的 main 函數(shù),其 函數(shù)體包括左花括號和與之匹配的右花括號之間的任何內(nèi)容 :
?
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 示例程序運行后控制臺會顯示:
?
所以,你可以把它叫做 "打印函數(shù)",通過 printf 函數(shù)將 Hello,World 打印到了控制臺上:
printf("需要打印到控制臺的內(nèi)容");
? 這里的 \n 為什么沒有被打印出來?
因為 \n 是轉(zhuǎn)義字符,用于換行,關(guān)于轉(zhuǎn)義字符的知識我們會放到下一章進行系統(tǒng)性講解。
0x03 分號,語句結(jié)束的標(biāo)志!
???在我們?nèi)粘I钪校?"句號" 表示一段話的結(jié)束。
而在 C 語言中,語句的結(jié)束用 ;?表示,分號是語句結(jié)束的標(biāo)志,表示一條語句的結(jié)束。
?可以看到,我們的 printf() 函數(shù)后面就有一個 分號?;
printf("Hello,World\n"); ?? 加分號
return 0; ?? 加分號
當(dāng)一條語句結(jié)束時,我們需要手動給它加上分號,表明該語句結(jié)束。
?
不加分號會報錯,人難免是會忘的,如果忘記加了編譯器會提示:
?
隨著敲代碼越來越熟練,忘記加分號的情況會越來越少的,就像你寫作文不會忘記加句號一樣。
遺漏分號會引發(fā) C2143 號報錯:error C2143: 語法錯誤: 缺少“;”?
當(dāng)然了,也不能在不該加分號的地方加分號!
如果你在 main() 后面直接加分號,那就表示語句直接結(jié)束了,后面的 { } 就會讓編譯器一臉懵……
?
所以,分號是初學(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é)了,并且把其中的知識點都講的差不多了。
??現(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ǔ)概念。
??這樣的開篇方式我們構(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í)一門編程語言?
?
我的編程母語是易語言(一款中文編程語言),我的編程啟蒙導(dǎo)師是覓風(fēng)。
覓風(fēng)老師在他的 《易語言視頻教程》中說過:
" 興趣是最好的老師。"
如果你對編程感興趣,那么這條路及時很艱難,你也會有無窮無盡的力量。
其次就是多動手,代碼眼看千遍不如手敲一遍,多動手去實操,畢竟:
" 紙上得來終覺淺,絕知此事要躬行。"
然后就是多看源碼,看看高手是怎么寫代碼的,大有裨益。
最后,遇到問題要深入了解,要具備對編程知識的求知欲,對問題要有鉆研精神。
?文章來源:http://www.zghlxwxcb.cn/news/detail-609937.html
|
?? [ 筆者 ]? ?王亦優(yōu) | 雷向明
?? [ 更新 ]? ?2023.6.29(初稿)| 2023.7.1(審稿結(jié)束)
? [ 勘誤 ]?? /* 暫無 */
?? [ 聲明 ]? ?由于作者水平有限,本文有錯誤和不準(zhǔn)確之處在所難免,
本人也很想知道這些錯誤,懇望讀者批評指正!
?? 參考文獻:文章來源地址http://www.zghlxwxcb.cn/news/detail-609937.html
|
到了這里,關(guān)于【C語言趣味教程】(1) 深入淺出 HelloWorld:夢開始的地方!通過 HelloWorld 展開教學(xué) | 頭文件詳解 | main 函數(shù)詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!