# 練習6:變量類型
> 原文:[Exercise 6: Types Of Variables](http://c.learncodethehardway.org/book/ex6.html)
> 譯者:[飛龍](https://github.com/wizardforcel)
你應該掌握了一個簡單的C程序的結構,所以讓我們執行下一步簡單的操作,聲明不同類型的變量。
```c
include <stdio.h>
int main(int argc, char *argv[])
{
int distance = 100;
float power = 2.345f;
double super_power = 56789.4532;
char initial = 'A';
char first_name[] = "Zed";
char last_name[] = "Shaw";
printf("You are %d miles away.\n", distance);
printf("You have %f levels of power.\n", power);
printf("You have %f awesome super powers.\n", super_power);
printf("I have an initial %c.\n", initial);
printf("I have a first name %s.\n", first_name);
printf("I have a last name %s.\n", last_name);
printf("My whole name is %s %c. %s.\n",
first_name, initial, last_name);
return 0;
}
```
在這個程序中我們聲明了不同類型的變量,并且使用了不同的`printf`格式化字符串來打印它們。
## 你會看到什么
你的輸出應該和我的類似,你可以看到C的格式化字符串相似于Python或其它語言,很長一段時間中都是這樣。
```sh
$ make ex6
cc -Wall -g ex6.c -o ex6
$ ./ex6
You are 100 miles away.
You have 2.345000 levels of power.
You have 56789.453200 awesome super powers.
I have an initial A.
I have a first name Zed.
I have a last name Shaw.
My whole name is Zed A. Shaw.
$
```
你可以看到我們擁有一系列的“類型”,它們告訴編譯器變量應該表示成什么,之后格式化字符串會匹配不同的類型。下面解釋了它們如何匹配:
整數
使用`int`聲明,使用`%d`來打印。
浮點
使用`float`或`double`聲明,使用`%f`來打印。
字符
使用`char`來聲明,以周圍帶有`'`(單引號)的單個字符來表示,使用`%c`來打印。
字符串(字符數組)
使用`char name[]`來生命,以周圍帶有`"`的一些字符來表示,使用`%s`來打印。
你會注意到C語言中區分單引號的`char`和雙引號的`char[]`或字符串。
> 注
> 當我提及C語言類型時,我通常會使用`char[]`來代替整個的`char SOMENAME[]`。這不是有效的C語言代碼,只是一個用于討論類型的一個簡化表達方式。
## 如何使它崩潰
你可以通過向`printf`傳遞錯誤的參數來輕易使這個程序崩潰。例如,如果你找到打印我的名字的那行,把`initial`放到`first_name`前面,你就制造了一個bug。執行上述修改編譯器就會向你報錯,之后運行的時候你可能會得到一個“段錯誤”,就像這樣:
```sh
$ make ex6
cc -Wall -g ex6.c -o ex6
ex6.c: In function 'main':
ex6.c:19: warning: format '%s' expects type 'char *', but argument 2 has type 'int'
ex6.c:19: warning: format '%c' expects type 'int', but argument 3 has type 'char *'
$ ./ex6
You are 100 miles away.
You have 2.345000 levels of power.
You have 56789.453125 awesome super powers.
I have an initial A.
I have a first name Zed.
I have a last name Shaw.
Segmentation fault
$
```
在`Valgrind`下運行修改后的程序,來觀察它會告訴你什么關于錯誤“Invalid read of size 1”的事情。
## 附加題
+ 尋找其他通過修改`printf`使這段C代碼崩潰的方法。
+ 搜索“`printf`格式化”,試著使用一些高級的占位符。
+ 研究可以用幾種方法打印數字。嘗試以八進制或十六進制打印,或者其它你找到的方法。
+ 試著打印空字符串,即`""`。
- 笨辦法學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” 已死