運行c程序的過程和簡單的c程序結構
運行c
程序的過程
編譯
編譯器可以將源代碼轉換成機器語言,在編譯過程中,會找出錯誤並報告。這個階段的輸入是在編輯期間產生的文件,常稱為源文件。
編譯器能找出程序中很多無效的和無法識別的錯誤,包括結構錯誤,例如程序的某個部分永遠不會執行。編譯器輸出的結構叫作對象代碼,存放它們的文件叫作對象文件。在Linux
中這些文件的擴展名通常是.o
,在Windows
下面這些文件的擴展名通常是.obj
。如果編譯成功就會生成一個文件,它與源文件同名。但擴展名為.o
或者.obj
。
其實我們在上一節編寫第一個C
語言程序的時候,使用的gcc -o 1-1 1-1.c
這條命令既包含了編譯也包含了鏈接,所以直接生成了可執行文件1-1
在Linux
下編譯是在源代碼文件所在目錄輸入以下命令(假如源代碼文件是上節課的 1-1.c):
gcc -c 1-1.c
這時源文件所在的目錄將會生成1-1.o
的文件。
鏈接
鏈接器將源代碼文件中由編譯器產生的各種對象模塊組合起來,再從C
語言提供的程序庫中添加必要的代碼模塊,將它們組合成一個可執行文件。鏈接器也可以檢測和報告錯誤,例如程序中引用了一個根本不存在的庫組件。鏈接一旦成功,就會生成可執行文件,在Windows
下面可執行文件的擴展名是.exe
,在Linux
下面,可執行文件沒有擴展名,但它的文件類型是可執行的。
在編譯生成 .o
文件的基礎上我們將會輸入以下命令(以編譯生成1-1.o
為例):
gcc -o 1-1 1-1.o
這時1-1.o
所在的目錄將會生成1-1
可執行文件。
多數情況下,我們是通過gcc -o 1-1 1-1.c
一次性完成編譯和鏈接。
執行
執行階段就是成功完成了前述的三個過程後,運行程序。但是這個階段可能會出現各種錯誤,包括輸出錯誤,計算機什麽也不做哦,甚至是計算機崩潰。無論如何,都需要我們返回編輯階段,檢查並修改源代碼。相信大家都還記得上一節課的執行命令,在文件所在目錄執行:
./1-1
創建C
程序的各個過程:
C語言的簡單結構
預處理指令
1-1.c
的第一行代碼如下:
嚴格地說,它不是可執行程序的一部分,但它很重要,事實上程序沒有它是不能執行的。符號#
表示這是一個預處理指令,告訴編譯器在編譯源代碼之前,要先執行一些操作。編譯器在編譯過程開始之前的預處理階段會處理這些指令。預處理指令的類型相當多,大多放於程序源文件的開頭。
在這個例子中,編譯器要將stdio.h
文件的內容包含進來,這個文件被稱為頭文件,因為通常放在程序的開頭處。在本例中,頭文件定義了 C 標準庫中一些函數的信息,本例要用到標準庫中的printf()
函數,所以必須包含 stdio.h
頭文件。stdio
是“ standard input & output ”的縮寫,包含了編譯器理解printf()
以及其它輸入 / 輸出函數所需要的信息。C
語言所有頭文件的擴展名都是.h
。在以後的學習過程中大家會看到很多其它的預處理指令。
main()函數
int main()
{
printf("Hello World!");
return 0;
}
main()
函數是“主函數”。每個C
程序都由一個或多個函數組成,但每個C
程序都必須有一個main()
函數——因為每個程序總是從這個函數開始執行。
程序的幾乎全部工作都是由各個函數分別完成的,函數是C
程序的基本單位,在設計良好的程序中,每個函數都用來實現一個或多個特定的功能。
一個C
語言程序由一個或者多個函數組成,其中必須包含一個main()
函數(且只能有一個main()
函數)。
一個函數包括兩個部分:
一是 函數首部
即函數的第一行:
int main()
二是 函數體
即函數首部下面的花括號內的部分:
{
}
printf()
函數
printf()
是C
編譯系統提供的函數庫中的輸出函數。printf()
函數中雙撇號內的字符串“Hello World!”按照原樣輸出,每個語句最後都有一個分號,表示語句結束。
運行c程序的過程和簡單的c程序結構