C語言做爲面向過程的高級程序設計語言,可以輕鬆的實現自頂向下的規劃、結構化編程和模塊化設計,這樣使得程序結構更加簡潔,可擴展性強以及更加容易維護。php
並且C語言有着高效(執行速度快)、功能強大(嵌套匯編)以及可移植性(標準庫可移植)、功能強大等優勢,並且也存在着對系統平臺庫依賴嚴重,因爲編程風格自由,經驗不足也會容易致使出錯,編寫代碼實現週期長,一樣的代碼在不一樣的操做系統(或者編譯器)下可能會有不一樣的表現等缺點。html
C語言偏向硬件驅動、操做系統、底層應用(數據庫、編譯器)、嵌入式應用開發、遊戲引擎等應用場景。java
硬件驅動的絕大部分實現是由C語言和彙編語言實現的。
主流操做系統(Unix,Linux,macOS,Windows,Android,iOS)的底層實現都是由C語言和部分彙編實現的。
C++,Java,Python,Swift的編譯器或者解釋器都是由C語言實現的。
Git,Nginx,Redis,MySQL,Apache,Linux Kernel都是使用C語言實現的,並且都是開放源代碼的,大部分代碼能夠在GitHub中獲取到,能夠經過閱讀源碼提高本身的設計和編碼能力。linux
HelloWorld是學習一門編程語言的入門程序,若是你能獨立編寫並運行HelloWorld,那麼就意味着邁入了編程的大門了。c++
Visual Studio Code是微軟推出的一款開源、跨平臺(Windows,Ubuntu,macOS)的編輯器,這裏使用它來編寫C語言的源代碼,固然除了編寫C代碼以外,還能夠用來編寫C++,Java,Python,Go,JavaScript,PHP程序等等。程序員
爲何首先要使用Visual Studio Code來編寫第一個C程序呢,由於Visual Studio Code只是一個編輯器,用於編寫源碼,並不提供編譯或者解釋運行程序的功能。
經過它來對比以前介紹的IDE,體驗下使用IDE開發程序帶來的好處,也有利於理解IDE背後的相關機制。web
在使用Visual Studio Code以前首先去官網下載
shell
而後傻瓜一鍵式安裝,安裝完成之後啓動Visual Studio Code會看到啓動界面。
數據庫
關於Visual Studio Code的詳細使用能夠參考官方提供的文檔。編程
1.在系統的D盤下建立目錄vs_code\c用於存放C語言的源程序(即C代碼)
2.在Visual Studio Code中將D:\vs_code\c目錄添加到工做區的文件夾
選擇D:\vs_code\c文件夾做爲Visual Studio開發C程序的工做區
3.在工做區D:\vs_code\c目錄下建立源文件helloworld.c,C語言的源文件都是以.c結尾的,並編寫如下內容
#include <stdio.h>
int main(int argc, char *argv[]){
printf("Windows10 1903 & Visual Studio Code Hello World With C \n");
return 0;
}
當源文件編輯好完成之後,須要安裝和配置gcc,由於Visual Studio Code並無提供編譯C程序的功能。
若是你以前已經下載安裝過Qt,那麼恭喜不用額外安裝gcc,由於Qt已經集成了編譯器。
只須要將gcc在Qt的bin目錄: C:\Qt\Qt5.13.0\Tools\mingw730_64\bin 添加至PATH環境變量便可。
當在終端上執行gcc命令時系統會從該目錄尋找gcc對應的可執行程序gcc.exe。
當gcc的PATH環境變量配置成功以後,即可以打開命令提示符(即終端),輸入gcc -v即可查看gcc版本信息
而後在終端上運行a.exe,程序會將字符串Windows10 1903 & Visual Studio Code Hello World With C輸出到終端上。
若是想要改變編譯生成的可執行文件名稱,使用gcc時可使用-o選項實現
剛纔在使用gcc編譯helloworld時一次性編譯連接生成了可執行文件(例如helloworld.exe),而實際上gcc在編譯程序時要經歷預處理、編譯、彙編、連接四個步驟,每一個步驟gcc都提供了對應的選項(連接除外),而且每一個步驟生成的文件後綴名也是不同的。
這裏編寫源文件gcc_compile_option.c,用於測試gcc的各個編譯選項,若是想要查看gcc命令的全部選項,可使用gcc --help
查看全部選項及其說明
#include <stdio.h>
#define PI 3.141592 //宏定義
int main(int argc, char *argv[]){
printf("PI = %f \n",PI);
return 0;
}
gcc預處理命令案例
gcc -E gcc_compile_option.c -o gcc_compile_option.i
這裏預編譯會將頭文件stdio.h的內容複製到gcc_compile_option.i頭文件中,而且將使用#define PI 3.141592的宏進行替換,所以最後運行程序時會看到終端上輸出PI =3.141592
gcc編譯案例
gcc -S gcc_compile_option.i -o gcc_compile_option.s
gcc彙編案例
gcc -c gcc_compile_option.c -o gcc_compile_option.o
gcc 連接案例
gcc gcc_compile_option.o -o gcc_compile_option.exe
目前主流的操做系統(Windows,Linux,macOS)都有完善的C語言集成開發環境,用於編輯、編譯、調試、打包部署C程序。
操做系統 | 開發工具 |
---|---|
Windows10 1903 | Visual Studio 2019 |
macOS10.15 | XCode10.3 |
Ubuntu18.04 | QT5.13 |
Windows做爲世界上最流行的桌面操做系統,當前最新版本爲Windows10 1903,VisualStudio做爲Windows上最強大的集成開發環境,能夠開發Windows軟件,遊戲,Web應用等等,最新版本爲VisualStudio2019 16.2.2。
XCode
除此之外還有些跨平臺的C/C++ 開發工具,例如來自Jetbrains公司的CLion也能夠用來編寫C/C++程序。
CLion
關於IDE的安裝以及使用,它們的官網都提供了詳細的教程,同窗們能夠自行去查閱。
C語言學習過程當中會使用Windows10 1903+Visual Studio 2019做爲主力開發環境,若是沒有特別的說明,默認的環境就是Windows10 1903和Visual Studio 2019。
建立新項目
選擇基於C++的空項目
配置新項目
設置項目名稱爲c-core-foundational,
項目路徑位於d:workspace\c\visualstudio2019,
解決方案名稱爲c-core。
Visual Studio 2019中一個解決方案會有多個項目。
而後編輯源文件
#include <stdio.h>
int main(int argc, char *argv[]) {
printf("Windows10 1903 & Visual Studio 2019 Hello World With C \n");
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
printf("Windows10 1903 & Visual Studio 2019 Hello World With C \n");
system("pause");
return 0;
}
此段程序是調用了跨平臺的輸入輸出函數實如今控制檯輸出Windows10 1903 & Visual Studio 2019 Hello World With C 並換行,而後等待用戶輸入任意鍵(一般習慣按回車鍵)後程序退出。
雖然該程序十分簡單,可是是C語言中可以運行的最小程序。後面編寫的程序都是在該基礎之上擴展的。
C語言中以#開頭的表示編譯時預處理階段須要處理的。
由於在main函數中使用了printf函數,可是該函數的聲明是在標準輸入輸出文件stdio.h頭文件中。所以須要使用#include <stdio.h>
將其包含在源文件helloworld.c中,該文件位於系統目錄 C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\stdio.h
而該函數的實如今系統庫文件中。
若是想要查看程序依賴了哪些庫文件,Ubuntu下可使用ldd命令查看
std表示跨平臺的,全部以std開頭的頭文件中聲明的函數都是能夠跨平臺(windows,linux,macOS)使用。
stdio表示標準輸入輸出,printf函數就是用於輸出,能夠將""包含的內容數據輸出到控制檯,文件甚至是網頁。而輸入函數有scanf,用於讀取鍵盤的輸入,實現程序的交互。該函數後期再介紹詳細使用。
若是想要在Visual Studio中查看系統提供的函數的定義,能夠選中函數,而後按快捷鍵F12即可查看,而返回可使用Ctrl+-實現。
爲了深刻理解#include的做用,這裏編寫一段程序。
首先在c-core-foundational的頭文件建立和源文件同樣目錄的篩選器net\ittimeline\c\core\foundational\object
而後定義頭文件include.h
而後將以前編寫的源文件helloworld.c的內容複製到include.h頭文件中
並在源文件的net\ittimeline\c\core\foundational\object\目錄下建立源文件include.c,該源文件中只須要使用#include <include.h>
包含以前編寫的頭文件便可。
而後運行程序,若是發現以下錯誤
1>include.obj : error LNK2005: _main 已經在 helloworld.obj 中定義
是由於在Visual Studio 中,解決方案的一個項目只能有一個main函數,若是包含了多個源文件,把其餘源文件的main函數重命名成其餘函數便可。
而後再次運行程序,程序結果和以前的helloworld運行結果是同樣的。
main函數是c/c++/java程序的入口函數,有且只能有一個,當程序執行時系統會自動調用惟一的main函數,程序從main函數開始執行。若是程序中編寫了其餘的函數,其餘的函數應該被main函數調用纔會獲得執行。
例如定義一個返回兩個整數相加的函數add,而後想要執行該函數,則必須在main函數調用。
#include <stdio.h>
#include <stdlib.h>
//自定義函數,返回兩個整數相加的結果
int add(int left,int right) {
return left + right;
}
int main(int argc, char* argv[]) {
int left = 10;
int right = 20;
//調用add函數,並定義變量保存結果
int result =add(left,right);
printf("%d + %d = %d",left,right,result);
system("pause");
return 0;
}
main函數左邊的的int表示函數的返回類型爲整數
main函數右邊的()表示函數的參數,經過傳遞參數,將外部數據傳入函數內部處理。
{}表示函數的函數體,函數具體作什麼事情,都寫在{}內,{}是成對出現的。
main函數中的 printf("Windows10 1903 & Visual Studio 2019 Hello World With C \n");
表示將Windows10 1903 & Visual Studio 2019 Hello World With C輸出到控制檯,\n表示換行。而;表示語句結束,C語言中的每條語句都要使用;表示結束,不然程序會編譯錯誤。
return 0 表示返回給系統0,並結束main函數,0表示main函數正常退出。
return以後的代碼都不會執行。
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[]) {
printf("Windows10 1903 & Visual Studio 2019 Hello World With C \n");
system("pause");
return 0;
printf("Windows10 1903 & Visual Studio 2019 Hello World With C again \n");
}
運行上面的程序,Windows10 1903 & Visual Studio 2019 Hello World With C again不會獲得輸出。
註釋是用於描述程序的功能,爲了便於程序後期的維護,在開發過程當中應該添加適量的註釋,編譯器在預編譯時會刪除註釋,因此註釋的內容不會影響程序的結果。
C語言中支持的註釋包含單行註釋(//
)和多行註釋(/**/
)兩種,單行註釋顧名思義就是註釋一行,多行註釋能夠註釋多行,須要注意的是多行註釋不可以嵌套使用,不然會發生編譯錯誤。
增長單行註釋和多行註釋後的helloworld程序
#include <stdio.h>
#include <stdlib.h>
/* main函數左邊的int是函數的返回值,右邊()的內容表示函數的參數,外部數據經過函數的參數傳遞到函數的內部處理。 {}表示函數的函數體,也就是函數執行的全部內容都包含在{}中,它是成對出現的。 @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version 2019/10/17 */
int main(int argc, char* argv[]) {
// printf函數是系統自帶的函數,用於將""包含的字符串按照指定的格式輸出到終端,終端能夠是控制檯、網頁或者是文件,目前是輸出到控制檯。
printf("Windows10 1903 & Visual Studio 2019 Hello World With C \n");
//等待輸入任意內容退出程序
system("pause");
return 0;
}
主流的操做系統(Windows,Linux(Ubuntu),MacOS)及大多數應用程序都提供了基於命令行和圖形化界面兩種交互方式,而移動端是採用手勢觸控、語音等進行交互。做爲普通用戶來說,圖形化界面容易上手,並且交互效果更加直觀。
可是做爲一個程序員來說,應該去熟悉各個操做系統的命令行的使用,由於命令行相對圖形化界面而言,絕大多數場景下使用更加高效。並且圖形化界面本質是對命令行的封裝,能用圖形化界面實現的基本均可以採用命令行實現。並且在服務器端(CentOS,RedHat)基本上是不會安裝圖形界面。
Windows下想要使用命令,必須首先啓動控制檯。
Windows系統可使用快捷鍵Windows+r調出運行
後輸入cmd,即可以進入Windows下的命令行終端
在啓動Windows的終端(也稱爲控制檯)以後,即可以運行命令了。若是你使用Windows做爲開發平臺,以下的命令你也許會常用到。
命令名稱 | 功能描述 |
---|---|
dir | 列出當前目錄列表 |
cd | 切換目錄(只能在根盤符(例如C盤)內切換),cd /切換到磁盤的根目錄 |
md | 建立目錄 |
rd | 刪除空目錄 |
del | 刪除文件 |
type | 顯示文本文件內容 |
echo | 輸出文本內容 例如echo %path% 查看系統環境變量 |
ping | 檢測網絡,例如ping baidu.com |
notepad | 記事本 |
calc | 計算器 |
mspaint | 畫圖 |
explore | 文件資源管理器 |
cleanmgr | 磁盤清理 |
desk.cpl | 分辨率設置 |
powercfg.cpl | 電源設置 |
regedit | 註冊表編輯器 |
msconfig | 系統配置 |
mstsc | 遠程鏈接 |
firewall.cpl | 防火牆 |
appwiz.cpl | 添加或修改程序 |
tasklist | 查看進程列表 |
taskkill /f /im process-name.exe | 關閉指定進程 |
netstat -ano|findstr "port" |
查看端口占用 |
msinfo | 系統信息 |
sticky notes | 便籤 |
ipconfig | 查看ip |
winver | 查看windows版本 |
cls | 清除屏幕內容 |
exit | 退出終端 |
在終端上使用命令時還有些快捷鍵,例如Tab能夠補全路徑,上下鍵能夠切換以前輸入的命令。*
實現模糊匹配操做,例如 del *.txt
就能夠刪除 指定目錄的全部文本文件。
若是想要獲取更多的windows命令信息,能夠在終端上輸入help回車後會顯示每一個命令的名稱以及功能說明。
system函數用於C程序中調用各大操做系統的命令和應用程序,被調用的命令和應用程序以字符串的方式做爲system函數的參數傳入,實現讀取用戶輸入的命令,並執行該命令。
在windows上運行該程序時能夠傳入notepad,calc等等實現程序調用。
而Linux和macOS上也有本身的命令能夠提供給system函數來調用。
這裏編寫一個交互式程序:經過藉助C語言的scanf函數讀取用戶在終端的命令,而後調用system函數來執行對應的命令。
若是你的開發環境不是Windows10 1903和Visual Studio 2019,能夠刪除#define _CRT_SECURE_NO_WARNINGS
。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/* 使用system函數調用各大操做系統的命令 @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version 2019/10/17 */
int main(int argc, char* argv[]) {
// 提示用戶輸入執行的命令
printf("請輸入須要執行的命令\n");
//定義字符串保存用戶輸入命令
char command[100] = {0};
//讀取用戶從鍵盤輸入的命令字符串,並保存到command中
scanf("%s",command);
//執行命令
system(command);
system("pause");
return 0;
}
由於system函數位於stdlib.h頭文件中,意味着它是一個能夠跨平臺使用的函數。
例如在Ubuntu下使用gedit命令調用文本編輯器
可是各大操做系統的命令和應用程序是不相同的,例如在Windows上使用system函數傳遞字符串參數"notepad"時能夠打開記事本,而移植到了類Unix上則沒法調用記事本。
在Visual Studio 2019中運行程序能夠經過快捷鍵F5直接運行,也能夠經過點擊本地Windows調試器運行。
可是發如今運行helloworld後程序有閃退現象,即程序運行時打開了終端後當即退出,其緣由是程序運行是printf函數默認輸出數據到終端,所以Visual Studio 2019開啓了終端,printf輸出數據完成之後,程序遇到return語句並退出,所以終端也會隨之退出,由於彈出終端和退終端的時間很是短,全部感受有閃退現象。
爲了解決這一問題,首先須要在源文件使用#include <stdlib.h>
包含標準庫頭文件,而後在main函數的最後一行加上system("pause")
,這樣程序運行時不會當即退出,而是等到用戶輸入任意鍵(通常習慣按回車鍵)纔會退出。
解決 helloworld在Visual Studio 2019運行的閃退問題
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
printf("Windows10 1903 & Visual Studio 2019 Hello World With C \n");
system("pause");
return 0;
}
再次運行程序時,在程序的末尾會輸出一句請按任意鍵繼續...
在平常使用Visual Studio 開發中會使用到以下經常使用的快捷鍵
快捷鍵名稱 | 功能 |
---|---|
Ctrl+k,f | 自動格式化代碼 |
Ctrl+k,c | 註釋代碼 |
Ctrl+k,u | 取消註釋代碼 |
Ctrl+F5 | 不調試運行 |
Ctrl+shift+b | 編譯,不運行 |
F12 | 查看函數定義 |
ctrl+- | 退出函數定義 |
F5 | 調試運行 |
F11 | 逐語句(遇到函數跳到函數內部逐語句執行) |
F10 | 逐過程 (不會進入函數內部,可是函數會被調用) |
Shift+F11 | 跳出 |
在後期編寫程序時,經驗不足的開發人員一般會遇到兩種錯誤:編譯錯誤和運行時錯誤,編譯錯誤一般是編寫的程序不知足編譯器的語法規範,而運行時錯誤則是程序運行時發生的錯誤,想要排查程序運行時的錯誤,就須要使用IDE提供的調試功能。
在源文件debug.c中定義一個返回兩個整數相乘的方法mul,而後在main函數中定義兩個變量做爲參數傳入mul方法中,並調用兩個整數相乘的方法,輸出計算結果
#include <stdlib.h>
/* 定義兩個整數相乘並返回 */
int mul(int source, int target) {
//打印輸出傳入mul方法的兩個整數參數的值
printf("source = %d\n",source);
printf("target = %d\n", target);
return source * target;
}
/* Visual Studio 2019的調試 @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version 2019/10/17 */
int main(int argc, char* argv[]) {
//定義兩個變量
int source = 12;
int target = 12;
//調用兩個整數相乘的方法,並將計算的結果保存到整數變量result中
int result = mul(source, target);
printf("result = %d \n",result);
system("pause");
return 0;
}
在調試程序前首先須要下斷點,可使用快捷鍵F9下斷點或者取消斷點
而後使用F5調試運行程序,程序會在以前下過斷點的地方暫停(不管是逐語句仍是逐過程),此時能夠在Visual Studio提供的自動窗口中觀察變量的值
若是想要一行一行調試代碼,可使用快捷鍵F11,當遇到函數時(例如這裏的mul函數),會進入函數的內部一行一行執行,直到該函數結束爲止。
若是調試時不想進入函數的內部,可使用快捷鍵F10,當程序中調用了其餘函數時不會進入其餘函數內部,可是函數會被調用。
若是調試時想要從一個斷點跳到另一個斷點,可使用shift+F11實現。
C4996是Visual Studio 2019提供的錯誤編號
首先明確下C4996錯誤出現錯誤的緣由:
Visual Studio 但願用戶使用Visual Studio提供的非標準庫函數,可是程序員但願使用標準庫函數,由於標準庫是能夠移植的。
若是在Visual Studio中使用標準的庫函數,就會引起C4996錯誤相似於這種提示:error C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details
.這裏的strcpy是標準的庫函數,而在Visual Studio中使用這個函數引起了C4996錯誤。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* 解決visual studio 2019 的C4996錯誤 @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version */
int main(int argc, char* argv[]) {
//定義一個字符串
char str[32] = "";
//將hi string 複製到str中
strcpy(str, "hi string");
printf("str = %s \n",str);
system("pause");
return 0;
}
那麼如何解決問題呢?
方案1:在源文件的第一行定義宏#define _CRT_SECURE_NO_WARNINGS
方案2:在源文件的第一行定義#pragma warning(disable:4996)
解決Visual Studio 2019的C4996錯誤的兩種方式
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:4996)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* 解決visual studio 2019 的C4996錯誤 error C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version */
int main(int argc, char* argv[]) {
//定義一個字符串
char str[32] = "";
//將hi string 複製到str中
strcpy(str, "hi string");
printf("str = %s \n",str);
system("pause");
return 0;
}
Visual Studio 2019提供了代碼片斷的功能,其做用就是配置代碼片斷後,能夠經過輸入指定的快捷鍵生成模板代碼,這樣能夠大大提升開發效率。
在後期編寫C程序中,須要反覆使用到以下的代碼片斷
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/* @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version */
int main(int argc, char* argv[]) {
return 0;
}
首先自定義代碼片斷文件MyCCode.snippet
<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Title>MyCCodeTemplate</Title>
<Shortcut>mcct</Shortcut>
<Description>c的標準模板代碼</Description>
<Author>Microsoft Corporation</Author>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
<SnippetType>SurroundsWith</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Code Language="cpp">
<![CDATA[#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
@author liuguanglei ittimelinedotnet@gmail.com
@website ittimeline.net
@version
*/
int main(int argc, char *argv[])
{
system("pause");
return 0;
}]]>
</Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>
而後選擇Visual Studio 2019 菜單 工具->代碼片斷管理器
選擇代碼片斷管理器的語言爲C++,而後選中My Code Snippets
而後爲導入的代碼片斷選擇一個位置
導入成功
導入成功以後新建任意的C程序源文件,在源文件中輸入快捷鍵mcct就能夠生成以下的代碼片斷
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/* @author liuguanglei ittimelinedotnet@gmail.com @website ittimeline.net @version */
int main(int argc, char* argv[]) {
system("pause");
return 0;
}
想要了解代碼片斷的更多內容,請移步官網