鍍金池/ 教程/ C/ 練習(xí)6:變量類型
練習(xí)9:數(shù)組和字符串
練習(xí)6:變量類型
練習(xí)3:格式化輸出
練習(xí)4:Valgrind 介紹
練習(xí)28:Makefile 進(jìn)階
練習(xí)14:編寫并使用函數(shù)
練習(xí)21:高級(jí)數(shù)據(jù)類型和控制結(jié)構(gòu)
練習(xí)20:Zed的強(qiáng)大的調(diào)試宏
練習(xí)18:函數(shù)指針
練習(xí)0:準(zhǔn)備
練習(xí)15:指針,可怕的指針
練習(xí)27:創(chuàng)造性和防御性編程
練習(xí)22:棧、作用域和全局
練習(xí)10:字符串?dāng)?shù)組和循環(huán)
練習(xí)8:大小和數(shù)組
練習(xí)16:結(jié)構(gòu)體和指向它們的指針
練習(xí)7:更多變量和一些算術(shù)
練習(xí)23:認(rèn)識(shí)達(dá)夫設(shè)備
練習(xí)12:If,Else If,Else
練習(xí)2:用Make來代替Python
練習(xí)1:啟用編譯器
練習(xí)11:While循環(huán)和布爾表達(dá)式
練習(xí)5:一個(gè)C程序的結(jié)構(gòu)
練習(xí)24:輸入輸出和文件
練習(xí)25:變參函數(shù)
練習(xí)13:Switch語句
練習(xí)19:一個(gè)簡單的對(duì)象系統(tǒng)
練習(xí)26:編寫第一個(gè)真正的程序
導(dǎo)言:C的笛卡爾之夢(mèng)
練習(xí)17:堆和棧的內(nèi)存分配

練習(xí)6:變量類型

你應(yīng)該掌握了一個(gè)簡單的C程序的結(jié)構(gòu),所以讓我們執(zhí)行下一步簡單的操作,聲明不同類型的變量。

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;
}

在這個(gè)程序中我們聲明了不同類型的變量,并且使用了不同的printf格式化字符串來打印它們。

你會(huì)看到什么

你的輸出應(yīng)該和我的類似,你可以看到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.
$

你可以看到我們擁有一系列的“類型”,它們告訴編譯器變量應(yīng)該表示成什么,之后格式化字符串會(huì)匹配不同的類型。下面解釋了它們?nèi)绾纹ヅ洌?/p>

整數(shù)

  使用int聲明,使用%d來打印。

浮點(diǎn)

  使用floatdouble聲明,使用%f來打印。

字符

  使用char來聲明,以周圍帶有'(單引號(hào))的單個(gè)字符來表示,使用%c來打印。

字符串(字符數(shù)組)

  使用char name[]來生命,以周圍帶有"的一些字符來表示,使用%s來打印。

你會(huì)注意到C語言中區(qū)分單引號(hào)的char和雙引號(hào)的char[]或字符串。

當(dāng)我提及C語言類型時(shí),我通常會(huì)使用char[]來代替整個(gè)的char SOMENAME[]。這不是有效的C語言代碼,只是一個(gè)用于討論類型的一個(gè)簡化表達(dá)方式。

如何使它崩潰

你可以通過向printf傳遞錯(cuò)誤的參數(shù)來輕易使這個(gè)程序崩潰。例如,如果你找到打印我的名字的那行,把initial放到first_name前面,你就制造了一個(gè)bug。執(zhí)行上述修改編譯器就會(huì)向你報(bào)錯(cuò),之后運(yùn)行的時(shí)候你可能會(huì)得到一個(gè)“段錯(cuò)誤”,就像這樣:

$ 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下運(yùn)行修改后的程序,來觀察它會(huì)告訴你什么關(guān)于錯(cuò)誤“Invalid read of size 1”的事情。

附加題

  • 尋找其他通過修改printf使這段C代碼崩潰的方法。
  • 搜索“printf格式化”,試著使用一些高級(jí)的占位符。
  • 研究可以用幾種方法打印數(shù)字。嘗試以八進(jìn)制或十六進(jìn)制打印,或者其它你找到的方法。
  • 試著打印空字符串,即""。