歡迎關注博主 Mindtechnist 或加入【智能科技社區】一起學習和分享Linux、C、C++、Python、Matlab,機器人運動控制、多機器人協作,智能優化算法,濾波估計、多傳感器信息融合,機器學習,人工智能等相關領域的知識和技術。關注公粽號 《機器和智能》 回復關鍵詞 “python項目實戰” 即可獲取美哆商城視頻資源!
博主介紹:
CSDN博客專家,CSDN優質創作者,CSDN實力新星,CSDN內容合伙人;
阿里云社區專家博主;
華為云社區云享專家;
51CTO社區入駐博主,掘金社區入駐博主,支付寶社區入駐博主,博客園博主。
C語言必備知識
- 1. 什么是編程語言
- 2. 程序和指令
- 3. 計算機語言的發展
- 4. CPU內部結構
- 5. C語言應用領域
- 6. 包含頭文件
- 7. main函數
- 8. 代碼塊與作用域
- 9. 代碼行與注釋
- 10. main函數參數與返回值
- 11. system函數
- 12. C程序的編譯過程
- 13. 開發環境
專欄:《精通C語言》
1. 什么是編程語言
編程語言就是人和計算機交流的語言。
2. 程序和指令
指令是對計算機進行程序控制的最小單位,指令的集合構成指令系統。而程序則是為完成一項特定任務而用某種計算機語言編寫的一組指令序列。
3. 計算機語言的發展
-
計算機的組成
-
機器語言:在上面的計算機組成中可以看到,中央處理器CPU起著控制整個計算機運作的作用,而CPU都有一個指令系統,這個指令系統就是機器語言,機器語言是直接控制計算機硬件工作的語言,它是由0和1二進制數(由硬件電路決定,電平只有高低兩種狀態)組成的指令碼,而這些指令碼一般是由CPU廠商從生產CPU時就規定好的,不同型號的計算機其機器語言是互不相通的。
-
匯編語言:機器語言是由計算機識別的0、1序列,應為計算機的硬件電路只有高電平和低電平兩種狀態。而對于人類來說,這些0、1序列顯然是不可讀的(沒有人會喜歡看一堆0、1數字吧)。這時候就出現了匯編語言,匯編語言通過標識符來代替0、1序列,對人類來說是可讀且易于理解的。但是,計算機只認識二進制的0和1,通過匯編語言是無法直接操作計算機硬件的。那么,如何把人類可讀的匯編語言轉換成計算機可讀的二進制0、1序列呢?這就有了編譯器,編譯器是一段用來做翻譯工作的程序,它既可以識別匯編語言又可以識別二進制機器語言,并且知道二者之間的對應關系。這樣,通過編譯器就可以把人類認識的匯編語言轉換成計算機認識的機器語言了。
-
高級語言:高級語言是更加通用和便捷的編程語言,通過高級語言,人們更加關注解決問題的邏輯和更高效的求解方式。高級語言有面向過程的C語言、面向對象的C++、Java、Python等。同樣,高級語言也需要編譯器來翻譯為機器語言。實際上,編程語言沒有高低之分,面向對象也并不一定就比面向過程高級,C語言一樣可以實現面向對象編程,Linus這種頂級大佬不就是使用C語言寫出了大名鼎鼎的Linux操作系統嗎,而C++、Java、Python等面向對象語言的底層也都是由C語言實現的。
4. CPU內部結構
- CPU的位數
CPU內部最基本的存儲單元是寄存器,CPU通過總線(地址、控制、數據)來和外部設備交互,總線的寬度是8位,同時CPU的寄存器也是8位,那么這個CPU就叫8位CPU。如果總線是32位,寄存器也是32位,那么這個CPU就是32位CPU。有一種CPU內部的寄存器是32位的,但總線是16位,這種叫做準32位CPU。所有的64位CPU兼容32位的指令,所以在64位的CPU上是可以識別32位的指令。在64位的CPU構架上運行了64位的軟件操作系統,那么這個系統是64位,在64位的CPU構架上,運行了32位的軟件操作系統,那么這個系統就是32位的,64位的軟件不能運行在32位的CPU之上。 - 寄存器、緩存、內存
CPU工作時,先預先把要用的數據從硬盤讀到內存,然后再把即將要用的數據讀到寄存器。也就是說CPU和寄存器進行交互,寄存器和內存進行交互( CPU<—>寄存器<—>內存)。我們知道,操作寄存器的速度遠遠大于操作內存的速度,緩存是為了緩沖二者之間的速度差,如果總是操作內存中的同一址地的數據,每次都去內存取值,會嚴重影響速度,于是就在寄存器與內存之間設置一個緩存,從緩存提取數據的速度遠高于內存(CPU<—>寄存器<—>緩存 <—> 內存)。
5. C語言應用領域
網站后臺、服務器、編寫其他語言、操作系統、驅動、嵌入式/物聯網、數據庫、編譯器等等。
6. 包含頭文件
頭文件的作用
- 通過頭文件提供的接口調用庫功能。對于源代碼的提供者不能或不愿將源代碼公布給用戶的情況,用戶需要通過頭文件或動/靜態鏈接庫來調用功能。通過頭文件提供的接口可以實現在隱藏底層實現邏輯的前提下向用戶提供功能,而用戶則在不關心接口實現邏輯的前提下可以調用庫功能,根據頭文件接口從庫中尋找代碼的任務由編譯器完成。
- 頭文件增強了編譯器的類型檢查。在使用接口時需要按照頭文件中聲明的接口形式進行傳參并接收返回值,如果調用實現和聲明形式不一致會引起編譯器報錯。
引入頭文件的兩種方式
- #include <>:將指定文件引入到當前文件,搜索策略為,直接在編譯器指定的路徑處開始搜索,如果找不到被引入文件,則程序報錯。因此系統提供的頭文件推薦使用這種方式引入。如果是集成開發環境,比如VS,這個默認路徑一般在VS安裝目錄下的一個名為 include 的路徑下。在Linux中,一般默認路徑是 /usr/include 或 /usr/lib 下的目錄。
- #include “”:將指定文件引入到當前文件,搜索策略為,首先在運行程序所在的目錄處進行搜索,搜索失敗后再到編譯器指定的路徑處搜索,如果仍然搜索失敗,則直接報錯。因此,用戶自定義頭文件必須用這種方式引入,系統提供的頭文件也可以使用這種方式,但是會增加沒必要的搜索,所以不推薦。
? 頭文件中一般要加#ifndef/#define/#endif來防止重復包含
7. main函數
一個完整的C語言程序,有且只能有一個main()函數(又稱主函數)和若干個其他功能函數結合而成,main()函數是必須要有的,而其它功能函數則根據實際需要選擇性添加。main函數是C語言程序的入口,程序是從main函數開始執行。
8. 代碼塊與作用域
{ }內部是一個代碼塊,也就是一個作用域,代碼塊執行完畢,作用域內的棧內存被自動釋放。在編程時{ }中的每一半括號都應占據單獨一行,并上下對齊,這不是C強制要求,而是一種編程規范。
9. 代碼行與注釋
- 可執行語句必須由分號;結尾
- 可執行語句必須在代碼塊{}內部(函數體內、作用域內)
- #開頭表示預編譯指令,不需要分號;結尾
- C語言只能以/**/注釋,盡量不要以//注釋
- C++中使用//進行行注釋,使用/**/進行代碼塊注釋
10. main函數參數與返回值
return語句表示函數執行完畢,一般寫main函數的時候,都應該定義為int類型返回值,即int main(int argc, char* argv[])。
實際上main函數也是有參數和返回值的,只不過我們在平時的學習中可能很少用到,main的返回值是int類型的,main函數的參數在Linux下編程用的還是比較多的。我們在運行一個可執行文件的時候可以在命令行傳入參數給argv[],也就是說argv[]是用來存放我們在命令行傳入的參數的,而參數argc用于統計參數的個數。不管我們傳不傳參數, argv[0]默認就是程序運行的路徑名。也就是說argc最小為1(命令行不傳參),argv[0]是程序運行路徑。
11. system函數
- 包含頭文件:
#include <stdlib.h> - 函數原型:
int system(const char *command); - 函數功能:
system() executes a command specified in command by calling /bin/sh -c command, and returns after the command has been completed. During execution of the command, SIGCHLD will be blocked, and SIGINT and SIGQUIT will be ignored. 該函數主要功能是在一個已經運行的程序中執行另一個程序。 - 函數返回值:
The value returned is -1 on error (e.g. fork(2) failed), and the return status of the command otherwise. - 函數的使用:
在使用VS寫程序的時候,如果你運行程序的時候,打印窗口一閃而逝,我們可以在main()函數的return語句前加一個system(“pause”); 來表示暫停。
12. C程序的編譯過程
C代碼編譯成可執行程序經過4步:
1)預處理:宏定義展開、頭文件展開、條件編譯等,同時將代碼中的注釋刪除,這里并不會檢查語法。
2)編譯:檢查語法,將預處理后文件編譯生成匯編文件。
3)匯編:將匯編文件生成目標文件(二進制文件)。
4)鏈接:C語言寫的程序是需要依賴各種庫的,所以編譯之后還需要把庫鏈接到最終的可執行程序中去。
GCC編譯流程
選項 | 含義 |
---|---|
-E | 只進行預處理 |
-S(大寫) | 只進行預處理和編譯 |
-c(小寫) | 只進行預處理、編譯和匯編 |
-o file | 指定生成的輸出文件名為 file |
1) 預處理
如果不加重定向的話,默認會把預處理后的信息輸出到標準輸出,所以如果想要保留預處理后的程序,需要重定向到一個文件。可以看到預處理后的.i文件非常大,遠遠大于源文件,這是因為預處理進行了一系列的代碼展開。
2) 編譯
生成匯編代碼
3) 匯編
4) 鏈接
生成可執行文件
13. 開發環境
本系列文章使用的開發環境及工具主要有:
-
Linux:VMware虛擬機、CentOS 6操作系統
-
Windows:Visual Studio 2019
-
遠程終端:SecureCRT
-
遠程編輯:UE編輯器
編寫C語言程序,可以使用Linux下的vim編輯器,在Windows系統可以直接使用IDE集成開發環境編寫,也可以使用各種編輯器編寫,比如notepad++、UE編輯器等等。編寫好的C程序必須經過編譯器編譯為二進制可執行代碼才能運行,在Linux操作系統中可以直接通過gcc命令或者編寫makefile腳本編譯程序,在Windows操作系統可以使用IDE(集成了代碼編輯器、編譯器、調試器和圖形用戶界面工具)的編譯功能直接編譯。
注意:
- Linux編譯后的可執行程序只能在Linux運行,Windows編譯后的程序只能在Windows下運行。
- 64位的Linux編譯后的程序只能在64位Linux下運行,32位Linux編譯后的程序只能在32位的Linux運行。
- 64位的Windows編譯后的程序只能在64位Windows下運行,32位Windows編譯后的程序可以在64位的Windows運行。
附:VS快捷鍵
VS快捷鍵 | 含義 |
---|---|
Ctrl + k,Ctrl + f | 自動格式化代碼 |
Ctrl + k,Ctrl + c | 注釋代碼 |
Ctrl + k,Ctrl + u | 取消注釋代碼 |
F9 | 設置斷點 |
F5 | 調試運行 |
Ctrl + F5 | 不調試運行 |
Ctrl + Shift + b | 編譯,不運行 |
F10 | next調試 |
F11 | step調試 |