第一個C語言程序 hello, world
盡管這個練習很簡單,但對於初學語言的人來說,它仍然可能成為一大障礙,因為要實 現這個目的,我們首先必須編寫程序文本,然后成功地運行編譯,並加載、運行,最后輸出 到某個地方。掌握了這些操作細節以后,其它事情就比較容易了。
// hello.c
#include <stdio.h> // 包含標准庫的信息
main() // 定義名為 main 的函數,它不接受參數值
{ // main 函數的語句都被括在花括號中
printf("hello, world\n"); // main 函數調用庫函數 printf 以顯示字符序列;
return 0;
}
注:在最新的C標准中,main函數前的類型為int而不是void
C語言的具體結構
簡單來說,一個C程序就是由若干頭文件
和函數
組成。
#include <stdio.h>
就是一條預處理命令, 它的作用是通知C語言編譯系統在對C程序進行正式編譯之前需做一些預處理工作函數
就是實現代碼邏輯的一個小的單元。
必不可少之主函數
一個C程序有且只有一個主函數,即main
函數。
- C程序就是執行主函數里的代碼,也可以說這個主函數就是C語言中的唯一入口。
- 而main前面的int就是主函數的類型.
printf()
是格式輸出函數,這里就記住它的功能就是在屏幕上輸出指定的信息- return是函數的返回值,根據函數類型的不同,返回的值也是不同的。
\n
是轉義字符中的換行符。(注意:C程序一定是從主函數開始執行的)
良好習慣之規范
- 一個說明或一個語句占一行,例如:包含頭文件、一個可執行語句結束都需要換行。
- 函數體內的語句要有明顯縮進,通常以按一下Tab鍵為一個縮進。
- 括號要成對寫,如果需要刪除的話也要成對刪除。
- 當一句可執行語句結束的時候末尾需要有分號。
- 代碼中所有符號均為英文半角符號。
程序解釋——注釋
注釋是寫給程序員看的,不是寫給電腦看的。
C語言注釋方法有兩種:
/* 多行注釋 */
// 單行注釋
C標識符
C語言規定,標識符可以是字母(A~Z,a~z)
、數字(0~9)
、下划線_
組成的字符串,並且第一個字符必須是字母或下划線。在使用標識符時還有注意以下幾點:
- 標識符的長度最好不要超過8位,因為在某些版本的C中規定標識符前8位有效,當兩個標識符前8位相同時,則被認為是同一個標識符。
- 標識符是嚴格區分大小寫的。例如
Imooc
和imooc
是兩個不同的標識符。 - 標識符最好選擇有意義的英文單詞組成做到"見名知意",不要使用中文。
- 標識符不能是C語言的關鍵字。想了解更多C語言關鍵字的知識。
變量及賦值
變量名由字母、數字、下划線組成,不能以數字開頭,不能和C關鍵字重名;變量在內存空間中的首地址稱為變量的地址
變量就是可以變化的量,而每個變量都會有一個名字(標識符)。變量占據內存中一定的存儲單元。使用變量之前必須先定義變量,要區分變量名和變量值是兩個不同的概念。
· 變量定義的一般形式為:數據類型 變量名;
· 多個類型相同的變量:數據類型 變量名, 變量名, 變量名...;
變量的存儲類型
注意:在定義中不允許連續賦值,如int a=b=c=5;
是不合法的。Ps:只會將c賦值為5
變量的賦值分為兩種方式:
- 先聲明再賦值
- 聲明的同時賦值
基本數據類型
最常用的整型, 實型與字符型(char,int,float,double):
整型數據是指不帶小數的數字(int,short int,long int, unsigned int, unsigned short int,unsigned long int):
注:
int
short int
long int
是根據編譯環境的不同,所取范圍不同。- 而其中
short int
和long int
至少是表中所寫范圍, 但是int
在表中是以16位編譯環境寫的取值范圍。 - 另外 c語言
int
的取值范圍在於他占用的字節數 ,不同的編譯器,規定是不一樣。 - ANSI標准定義
int
是占2個字節,TC是按ANSI標准的,它的int
是占2個字節的。但是在VC里,一個int
是占4個字節的。
要把一個較小的常量作為long類型對待,可以在值的末尾加上l(小 寫的L)或L后綴。使用L后綴更好,因為l看上去和數字1很像。因此,在int 為16位、long為32位的系統中,會把7作為16位儲存,把7L作為32位儲存。l 或L后綴也可用於八進制和十六進制整數,如020L和0x10L。
浮點數據是指帶小數的數字。因為精度的不同又分為3種(float,double,long double):
// some = 4.0 * 2.0;
// 通常,4.0和2.0被儲存為64位的double類型,使用雙精度進行乘法運 算,然后將乘積截斷成float類型的寬度。這樣做雖然計算精度更高,但是會 減慢程序的運行速度。
// 在浮點數后面加上f或F后綴可覆蓋默認設置,編譯器會將浮點型常量看 作float類型,如2.3f和9.11E9F。
// 使用l或L后綴使得數字成為long double類 型,如54.3l和4.32L。注意,建議使用L后綴,因為字母l和數字1很容易混 淆。沒有后綴的浮點型常量是double類型。
不可改變的常量
在程序執行過程中,值不發生改變的量稱為常量。
mtianyan: C語言的常量可以分為直接常量和符號常量。
直接常量也稱為字面量,是可以直接拿來使用,無需說明的量,比如:
- 整型常量:13、0、-13;
- 實型常量:13.33、-24.4;
- 字符常量:‘a’、‘M’
- 字符串常量:”I love imooc!” // 字符串以 "\0結尾"
在C語言中,可以用一個標識符來表示一個常量,稱之為符號常量。符號常量在使用之前必須先定義,其一般形式為:
#define 標識符 常量值
#include <stdio.h>
#define POCKETMONEY 10 //定義常量及常量值
int main()
{
// POCKETMONEY = 12; //小明私自增加零花錢對嗎?
printf("小明今天又得到%d元零花錢\n", POCKETMONEY);
return 0;
}
Ps:符號常量不可以被改變。
自動類型轉換
數據類型存在自動轉換的情況.
自動轉換發生在不同數據類型運算時,在編譯的時候自動完成。
char
類型數據轉換為int
類型數據遵循ASCII
碼中的對應值.
注:
字節小的可以向字節大的自動轉換,但字節大的不能向字節小的自動轉換
char可以轉換為int,int可以轉換為double,char可以轉換為double。但是不可以反向。
強制類型轉換
強制類型轉換是通過定義類型轉換運算來實現的。其一般形式為:
(數據類型) (表達式)
其作用是把表達式的運算結果強制轉換成類型說明符所表示的類型
在使用強制轉換時應注意以下問題:
- 數據類型和表達式都必須加括號, 如把
(int)(x/2+y)
寫成(int)x/2+y
則成了把x
轉換成int
型之后再除2
再與y
相加了。 - 轉換后不會改變原數據的類型及變量值,只在本次運算中臨時性轉換。
- 強制轉換后的運算結果不遵循四舍五入原則。
編譯
cc hello.c
執行(如果源程序沒有什么錯誤(例如漏掉字符或拼錯字符),編譯過程將順利進行,並生成一個可 執行文件 a.out。然后,我們輸入:)
./a.out
輸出
hello, world
Gcc編譯器
gcc hello.c -o hello
gcc [options][filenames]
// -o 輸出可執行文件
// -c 只要求編譯器輸出目標代碼(.o文件),而不必輸出可執行文件
// -g 用於調試
// -0 對程序進行優化編譯、連接,會慢
// -02 比-0更好 會更慢
// -Wall 代碼規范檢測
// -i dirname 將dirname指出的目錄加入頭文件目錄列表中,是在預編譯使用的參數
// -l dirname 將dirname指出的目錄加入到程序函數檔案庫文件的目錄列表中,在鏈接過程中使用的參數
// -E 預處理輸出 // gcc -E xxx.c -o xxx.i
gcc hello.c // 輸出 a.out
gcc hello.c xxx // 輸出 xxx 文件
// -S 生成匯編文件 *.s
### Debug打印錯誤格式
```c
printf("%s,%s,%d xxx = %d\n",__FILE__,__FUNCTION__,__LINE__,i); // xxx 想輸出的內容 文件,函數,行數,想輸出內容
常見錯誤
語法錯誤
文件source.c中第n行有語法錯誤(syntex error)
頭文件錯誤
找不到頭文件head.h(Can not find include file head.h)
檔案庫錯誤
鏈接程序找不到所需的函數庫(ld:-lm:No such file or directory)
未定義符號
有未定義的符號(Undefined symbol)
GCC編譯過程
- 預處理(Pre-Processing)
將#
開頭的內容進行替換 生成*.i文件 - 編譯(Compiling)
將預處理后的.i文件進行編譯成.s匯編文件 - 匯編(Assembling)
將.s匯編文件匯編處理生成生成.o文件 - 鏈接(Linking)
將.o加上鏈接生成.exe可執行文件 -lm
Gdb調試流程
gdb 調試的文件name 進入交互(一定是在編譯的時候加入 -g指令才能運行)
-(gdb) l num 查看文件 每十行一頁 num跳頁
-(gdb) b num 設置num行斷點
-(gdb) del num 刪除斷點 這里的num不是行號 是加入斷點的額順序 可以在info b查看順序
-(gdb) info b 查看斷點情況
-(gdb) r 運行代碼
-(gdb) p 變量名 查看變量值
-(gdb) n/s 單步運行
-(gdb) c 恢復運行
-(gdb) set 參數 等於是在運行程序時候傳參
-(gdb) help 幫助