# 練習5:一個C程序的結構
> 原文:[Exercise 5: The Structure Of A C Program](http://c.learncodethehardway.org/book/ex5.html)
> 譯者:[飛龍](https://github.com/wizardforcel)
你已經知道了如何使用`printf`,也有了可以隨意使用的一些工具,現在讓我們逐行分析一個簡單的C程序,以便你了解它是如何組織的。在這個程序里你會編寫一些不是很熟悉的東西,我會輕松地把它們拆開。之后在后面的幾章我們將會處理這些概念。
```c
#include <stdio.h>
/* This is a comment. */
int main(int argc, char *argv[])
{
int distance = 100;
// this is also a comment
printf("You are %d miles away.\n", distance);
return 0;
}
```
手動輸入這段代碼并運行它,之后確保在`Valgrind`下不出現任何錯誤。你可能不會這樣做,但你得習慣它。
## 你會看到什么
這真是一段無聊的輸出,但是這個練習的目的是讓你分析代碼:
```sh
$ make ex5
cc -Wall -g ex5.c -o ex5
$ ./ex5
You are 100 miles away.
$
```
## 分解代碼
當你輸出這段代碼時,可能你只弄清楚了這段代碼中的一小部分C語言特性。讓我們快速地逐行分解它,之后我們可以做一些練習來更好地了解每一部分:
ex5.c:1
這是一個`include`,它是將一個文件的內容導入到這個文件的方式。C具有使用`.h`擴展名作為頭文件的慣例。頭文件中擁有一些函數的列表,這些都是你想在程序中使用的函數。
ex5.c:3
這是多行注釋,你可以在`/*`和`*/`之間放置任意多行。
ex5.c:4
這是一個你遇到的更復雜的 `main` 函數。操作系統加載完你的程序,之后會運行叫做`main`的函數,這是C程序的工作方式。這個函數只需要返回`int`,并接受兩個參數,一個是`int`作為命令行參數的數量,另一個是`char*`字符串的數組作為命令行參數。這是不是讓人難以理解?不用擔心,我們稍后會講解它。
ex5.c:5
任何函數都以`{`字符開始,它表示“程序塊”的開始。在Python中用一個`:`來表示。在其它語言中,可能需要用`begin`或者`do`來表示。
ex5.c:6
一個變量的聲明和同時的賦值。你可以使用語法`type name = value;`來創建變量。在C的語句中,除了邏輯語句,都以一個`;`(分號)來結尾。
ex5.c:8
注釋的另一種形式,它就像Python或Ruby的注釋。它以`//`開頭,直到行末結束。
ex5.c:9
調用了我們的老朋友`printf`。就像許多語言中的函數調用,使用語法`name(arg1, arg2);`。函數可以不帶任何參數,也可以擁有任何數量的參數。`printf`函數是一類特別的函數,可以帶可變數量的參數。我們會在之后說明。
ex5.c:11
一個`main`函數的返回語句,它會向OS提供退出值。你可能不熟悉Unix軟件的返回代碼,所以這個也放到后面去講。
ex5.c:12
最后,我們以一個閉合的`}`花括號來結束了`main`函數。它就是整個程序的結尾了。
在這次分解中有大量的信息,所以你應該逐行來學習,并且確保至少掌握了背后發生了什么。你不一定了解所有東西,但是在我們繼續之前,你可以猜猜它們的意思。
## 附加題
+ 對于每一行,寫出你不理解的符號,并且看看是否能猜出它們的意思。在紙上寫下你的猜測,你可以在以后檢查它,看看是否正確。
+ 回頭去看之前幾個練習的源代碼,并且像這樣分解代碼,來看看你是否了解它們。寫下你不了解和不能自己解釋的東西。
- 笨辦法學C 中文版
- 前言
- 導言:C的笛卡爾之夢
- 練習0:準備
- 練習1:啟用編譯器
- 練習2:用Make來代替Python
- 練習3:格式化輸出
- 練習4:Valgrind 介紹
- 練習5:一個C程序的結構
- 練習6:變量類型
- 練習7:更多變量和一些算術
- 練習8:大小和數組
- 練習9:數組和字符串
- 練習10:字符串數組和循環
- 練習11:While循環和布爾表達式
- 練習12:If,Else If,Else
- 練習13:Switch語句
- 練習14:編寫并使用函數
- 練習15:指針,可怕的指針
- 練習16:結構體和指向它們的指針
- 練習17:堆和棧的內存分配
- 練習18:函數指針
- 練習19:一個簡單的對象系統
- 練習20:Zed的強大的調試宏
- 練習21:高級數據類型和控制結構
- 練習22:棧、作用域和全局
- 練習23:認識達夫設備
- 練習24:輸入輸出和文件
- 練習25:變參函數
- 練習26:編寫第一個真正的程序
- 練習27:創造性和防御性編程
- 練習28:Makefile 進階
- 練習29:庫和鏈接
- 練習30:自動化測試
- 練習31:代碼調試
- 練習32:雙向鏈表
- 練習33:鏈表算法
- 練習34:動態數組
- 練習35:排序和搜索
- 練習36:更安全的字符串
- 練習37:哈希表
- 練習38:哈希算法
- 練習39:字符串算法
- 練習40:二叉搜索樹
- 練習41:將 Cachegrind 和 Callgrind 用于性能調優
- 練習42:棧和隊列
- 練習43:一個簡單的統計引擎
- 練習44:環形緩沖區
- 練習45:一個簡單的TCP/IP客戶端
- 練習46:三叉搜索樹
- 練習47:一個快速的URL路由
- 后記:“解構 K&R C” 已死