C 程式設計/入門練習
傳統上,我們從一個顯示“Hello, World!”問候語到螢幕,然後換行並退出程式開始。以下是用 C 語言編寫的原始碼,可以實現這個功能。將這段程式碼輸入你喜歡的文字編輯器/IDE,並將其儲存到一個名為hello.c的檔案中。
#include <stdio.h> int main(void) { printf("Hello, World!\n"); return 0; }
雖然這是一個非常簡單的程式,但在你看到的程式碼中包含了很多隱含的含義。雖然你的編譯器理解它,但你只能猜測程式碼(散佈著一些熟悉的英文單詞)可能會做什麼。作為一名新程式設計師,你的第一個工作之一就是學習 C 程式語言的許多“單詞”和符號,這是你的編譯器所理解的語言。一旦你瞭解程式碼背後的含義,你就可以“與”編譯器“交談”,並給它下達你自己的命令,並構建任何你具有足夠的創造力和資源可以建立的程式。
但需要注意的是,瞭解神秘符號的含義並不是程式設計的全部。你不能透過閱讀翻譯詞典來掌握另一種語言。要精通另一種語言,你必須練習用這種語言交談。學習程式語言也是一樣的。你必須練習用你編寫的原始碼與編譯器“交談”。因此,請務必輸入上面的程式碼示例,並根據你的好奇心隨意進行實驗和修改。
好的,讓我們深入瞭解我們程式的第一行
#include <stdio.h>
在你理解這一行做了什麼之前,你必須知道你的機器已經預裝了一些 C 軟體程式碼。這些程式碼是為了讓你免於編寫執行基本、常見任務的程式碼的繁瑣工作。這種可重用的程式碼被稱為庫。因此,我們示例程式的第一行向編譯器發出訊號,我們想從庫中“檢視”一些程式碼,並在我們的程式中使用它。在這裡,我們借用了幫助我們列印文字到螢幕的程式碼。
我們告訴 C 編譯器將庫程式碼包含到我們自己的程式碼中的方法是使用被稱為預處理器指令的東西。你的編譯器將執行的最早任務之一是在你的原始碼中搜索預處理器指令,這些指令會以某種方式修改你的原始碼。在我們的例子中,#include 預處理器指令告訴編譯器從庫中複製原始碼,並將其直接插入到找到預處理器指令的程式碼中。由於我們的指令位於檔案的頂部,庫程式碼將插入到原始檔的頂部。(請注意,所有這些操作都發生在計算機的記憶體中,因此磁碟上的原始檔案實際上永遠不會被修改。)
但是編譯器應該插入哪個庫程式碼呢?這一行中的下一部分,<stdio.h>,告訴編譯器從stdio.h檔案中複製和貼上 C 程式碼到你的程式碼中。圍繞檔名的一對尖括號告訴編譯器在標準庫中查詢該檔案,而不是說你自己的可重用程式碼庫。請注意,副檔名為.h的檔案被稱為標頭檔案。stdio.h 標頭檔案包含許多與輸入和輸出相關的函式,這些函式是根據 C 標準定義的。雖然這個標頭檔案讓我們可以使用許多不同的函式,但我們感興趣的 stdio.h 中唯一一個庫函式是printf 函式。
好的,但是函式到底是什麼呢?讓我們看看我們程式碼中的下一行,這樣我們就可以開始瞭解它了
int main(void)
在這裡,我們建立了一個名為main的函式,它是所有 C 程式的起點。所有 C 程式都需要一個名為“main”的函式,否則它們將無法編譯。我們的函式名稱被兩個神秘的符號包圍,int 和 (void)。“int”部分告訴編譯器我們的函式將返回什麼型別的數值,而“(void)”部分告訴我們的編譯器我們將向我們的函式“傳遞”什麼型別的數值。我們現在暫時跳過這到底是什麼意思,因為這些值將在本書後面的章節中詳細介紹。現在最重要的是要了解,這些符號一起宣告我們的函式給編譯器,並告訴它函式存在。
那麼函式是什麼呢?在計算機科學中,“函式”這個詞的含義比在數學中要寬泛一些,因為函式通常表達命令式的想法(比如 C 語言中的情況)——也就是說,如何進行處理,而不是宣告。現在,只需說,函式定義了一組一起工作以完成特定任務的計算機語句。在 C 語言中,與函式相關的語句放在一對花括號{ }之間,它們標記著語句的開始和結束。花括號和語句一起被稱為程式碼塊。讓我們看看我們函式程式碼塊中的第一行
printf("Hello World!\n");
這行程式碼是我們程式的核心,是將問候語輸出到使用者控制檯(在類Unix作業系統環境中也稱為終端,即安裝在你計算機上的基於文字的介面)的程式碼。這個語句是一個函式呼叫,它主要有兩部分:用來列印問候語的庫函式的名稱,printf,以及我們將傳遞給函式的資料,在這裡看到的是一對括號之間的部分。我們傳遞給函式的資料是字串,“Hello World!\n”。字串末尾的“\n”部分是一種特殊型別的字元,稱為轉義序列。“\n”轉義序列在文字末尾生成換行符。字串和轉義序列將在後面詳細介紹。我們在函式呼叫語句的末尾用分號結束,這樣編譯器就知道它應該開始尋找新的語句,它在下一行找到了它
return 0;
在這裡,我們使用return關鍵字說明我們的main函式返回一個整數型別的值。我們返回的整數值是“0”。但是這到底意味著什麼呢?在main函式的特定上下文中,我們返回的值稱為退出狀態,我們將其報告回作業系統,以指示我們的程式碼是否執行沒有錯誤。隨著我們的程式變得越來越複雜,我們可以使用其他整數作為程式碼來指示各種型別的錯誤。這種提供退出狀態的風格是一個長期的約定[1]。我們將在本書後面的章節中更詳細地介紹函式的返回值。
所以對於這樣一個簡短的程式來說,我們要學習的內容很多。如果你沒有完全理解它,或者沒有記住它,不要擔心。你不是透過記憶來學習程式設計,而是透過重複和實踐來學習。記住貝多芬第五交響曲的所有音符並不能讓你成為一名鋼琴演奏家,你必須坐在鍵盤前練習和演奏!
接下來,我們將向你展示如何使用你的編譯器將你輸入的原始碼轉換成可執行檔案。
編譯是我們用來描述將你給編譯器下達的指令(在你的原始碼中)轉換成你的作業系統和微處理器可以執行的機器語言的過程。這樣,你的 C 編譯器就是一箇中間人。你用編譯器可以理解的語言(C 原始碼)與編譯器交談,編譯器將原始碼轉換成機器程式碼,為你省去了大量編寫彙編程式碼的痛苦和繁瑣工作。
如果編譯器發現您的原始碼令人困惑,它會丟擲一個錯誤以及一條訊息來幫助您修復原始碼並消除任何混淆。然後,您需要嘗試重新編譯程式碼並重復此過程,直到它在沒有錯誤的情況下編譯。請注意,沒有錯誤的程式碼並不意味著它沒有錯誤。它只是意味著編譯器理解您的原始碼提供的指令。
如果您使用的是類 Unix 系統,例如 GNU/Linux、Mac OS X 或 Solaris,它很可能已經安裝了 GCC,否則在 Linux 上,您可以使用您發行版的包管理器安裝它。開啟虛擬控制檯或終端模擬器並輸入以下內容(確保您的當前工作目錄是包含您的原始碼的目錄)
gcc hello.c
預設情況下,gcc 會生成我們的可執行二進位制檔案,名稱為 a.out。要執行您新生成程式,請鍵入
./a.out
您應該在最後一個提示符之後看到 Hello, World! 打印出來。
要檢視您執行的最後一個程式的退出狀態,請在您的 shell 命令中鍵入
echo $?
這顯示了 main 函式返回的值,在本例中為 0。
您可以使用許多選項與 gcc 編譯器一起使用。例如,如果您希望輸出具有與 a.out 不同的名稱,則可以使用 -o 選項。以下顯示了一些示例
-o- 表示下一個引數是結果程式(或庫)的名稱。如果未指定此選項,出於歷史原因,已編譯程式最終將位於名為“a.out”或“a.exe”的檔案中(對於 cygwin 使用者)。
-Wall- 表示 gcc 應該警告可能不正確的許多型別可疑程式碼。
您可以使用這些選項建立一個名為“helloworld”的程式,而不是“a.out”,方法是鍵入
gcc -o helloworld hello.c -Wall
現在您可以透過鍵入以下內容執行它
./helloworld
所有選項在 GCC 的手冊[2] 中都有詳細的說明。
如果您使用的是 IDE,您可能需要選擇控制檯專案,要編譯,您只需從選單或工具欄中選擇構建即可。可執行檔案將出現在專案資料夾中,但您應該有一個選單按鈕,因此您可以直接從 IDE 執行可執行檔案。該過程在所有 IDE 上大致相同。