笨辦法學(xué)C 練習(xí)8:大小和數(shù)組

練習(xí)8:大小和數(shù)組

原文:Exercise 8: Sizes And Arrays

譯者:飛龍

在上一個練習(xí)中你做了一些算術(shù)運(yùn)算,不過帶有'\0'(空)字符物遇。這對于其它語言來說非常奇怪,因為它們把“字符串”和“字節(jié)數(shù)組”看做不同的東西费薄。但是C中的字符串就是字節(jié)數(shù)組,并且只有不同的打印函數(shù)才知道它們的不同。

在我真正解釋其重要性之前赚爵,我先要介紹一些概念:sizeof和數(shù)組。下面是我們將要討論的一段代碼:

#include <stdio.h>

int main(int argc, char *argv[])
{
    int areas[] = {10, 12, 13, 14, 20};
    char name[] = "Zed";
    char full_name[] = {
        'Z', 'e', 'd',
         ' ', 'A', '.', ' ',
         'S', 'h', 'a', 'w', '\0'
    };

    // WARNING: On some systems you may have to change the
    // %ld in this code to a %u since it will use unsigned ints
    printf("The size of an int: %ld\n", sizeof(int));
    printf("The size of areas (int[]): %ld\n",
            sizeof(areas));
    printf("The number of ints in areas: %ld\n",
            sizeof(areas) / sizeof(int));
    printf("The first area is %d, the 2nd %d.\n",
            areas[0], areas[1]);

    printf("The size of a char: %ld\n", sizeof(char));
    printf("The size of name (char[]): %ld\n",
            sizeof(name));
    printf("The number of chars: %ld\n",
            sizeof(name) / sizeof(char));

    printf("The size of full_name (char[]): %ld\n",
            sizeof(full_name));
    printf("The number of chars: %ld\n",
            sizeof(full_name) / sizeof(char));

    printf("name=\"%s\" and full_name=\"%s\"\n",
            name, full_name);

    return 0;
}

這段代碼中我們創(chuàng)建了一些不同數(shù)據(jù)類型的數(shù)組宴霸。由于數(shù)組是C語言工作機(jī)制的核心囱晴,有大量的方法可以用來創(chuàng)建數(shù)組。我們暫且使用type name[] = {initializer};語法瓢谢,之后我們會深入研究畸写。這個語法的意思是,“我想要那個類型的數(shù)組并且初始化為{..}”氓扛。C語言看到它時枯芬,會做這些事情:

  • 查看它的類型,以第一個數(shù)組為例采郎,它是int千所。
  • 查看[],看到了沒有提供長度蒜埋。
  • 查看初始化表達(dá)式{10, 12, 13, 14, 20}淫痰,并且了解你想在數(shù)組中存放這5個整數(shù)。
  • 在電腦中開辟出一塊空間整份,可以依次存放這5個整數(shù)待错。
  • 將數(shù)組命名為areas籽孙,也就是你想要的名字,并且在當(dāng)前位置給元素賦值火俄。

areas的例子中犯建,我們創(chuàng)建了一個含有5個整數(shù)的數(shù)組來存放那些數(shù)字。當(dāng)它看到char name[] = "Zed";時瓜客,它會執(zhí)行相同的步驟适瓦。我們先假設(shè)它創(chuàng)建了一個含有3個字符的數(shù)組,并且把字符賦值給name谱仪。我們創(chuàng)建的最后一個數(shù)組是full_name,但是我們用了一個比較麻煩的語法疯攒,每次用一個字符將其拼寫出來揭芍。對C來說,namefull_name的方法都可以創(chuàng)建字符數(shù)組。

在文件的剩余部分呜舒,我們使用了sizeof關(guān)鍵字來問C語言這些東西占多少個字節(jié)。C語言無非是內(nèi)存塊的大小和地址以及在上面執(zhí)行的操作笨奠。它向你提供了sizeof便于你理解它們袭蝗,所以你在使用一個東西之前可以先詢問它占多少空間。

這是比較麻煩的地方般婆,所以我們先運(yùn)行它到腥,之后再解釋。

你會看到什么

$ make ex8
cc -Wall -g    ex8.c   -o ex8
$ ./ex8
The size of an int: 4
The size of areas (int[]): 20
The number of ints in areas: 5
The first area is 10, the 2nd 12.
The size of a char: 1
The size of name (char[]): 4
The number of chars: 4
The size of full_name (char[]): 12
The number of chars: 12
name="Zed" and full_name="Zed A. Shaw"
$

現(xiàn)在你可以看到這些不同printf調(diào)用的輸出蔚袍,并且瞥見C語言是如何工作的乡范。你的輸出實際上可能會跟我的完全不同,因為你電腦上的整數(shù)大小可能會不一樣啤咽。下面我會過一遍我的輸出:

譯者注:16位機(jī)器上的int是16位的晋辆,不過現(xiàn)在16位機(jī)很少見了吧。

5

我的電腦認(rèn)為int的大小是4個字節(jié)宇整。你的電腦上根據(jù)位數(shù)不同可能會使用不同的大小瓶佳。

6

areas中含有5個整數(shù),所以我的電腦自然就需要20個字節(jié)來儲存它鳞青。

7

如果我們把areas的大小與int的大小相除霸饲,我們就會得到元素數(shù)量為5为朋。這也符合我們在初始化語句中所寫的東西。

8

接著我們訪問了數(shù)組贴彼,讀出areas[0]areas[1]潜腻,這也意味著C語言的數(shù)組下標(biāo)是0開頭的,像Python和Ruby一樣器仗。

9~11

我們對name數(shù)組執(zhí)行同樣的操作融涣,但是注意到數(shù)組的大小有些奇怪,它占4個字節(jié)精钮,但是我們用了三個字符來打出"Zed"威鹿。那么第四個字符是哪兒來的呢?

12~13

我們對full_name數(shù)組執(zhí)行了相同的操作轨香,但它是正常的忽你。

13

最后我們打印出namefull_name,根據(jù)printf證明它們實際上就是“字符串”臂容。

確保你理解了上面這些東西科雳,并且知道這些輸出對應(yīng)哪些創(chuàng)建的變量。后面我們會在它的基礎(chǔ)上探索更多關(guān)于數(shù)組和存儲空間的事情脓杉。

如何使它崩潰

使這個程序崩潰非常容易糟秘,只需要嘗試下面這些事情:

  • full_name最后的'\0'去掉,并重新運(yùn)行它球散,在valgrind下再運(yùn)行一遍∧蜃現(xiàn)在將full_name的定義從main函數(shù)中移到它的上面,嘗試在Valgrind下運(yùn)行它來看看是否能得到一些新的錯誤蕉堰。有些情況下凌净,你會足夠幸運(yùn),不會得到任何錯誤屋讶。
  • areas[0]改為areas[10]并打印冰寻,來看看Valgrind會輸出什么。
  • 嘗試上述操作的不同變式丑婿,也對namefull_name執(zhí)行一遍性雄。

附加題

  • 嘗試使用areas[0] = 100;以及相似的操作對areas的元素賦值。
  • 嘗試對namefull_name的元素賦值羹奉。
  • 嘗試將areas的一個元素賦值為name中的字符秒旋。
  • 上網(wǎng)搜索在不同的CPU上整數(shù)所占的不同大小。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末诀拭,一起剝皮案震驚了整個濱河市迁筛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌耕挨,老刑警劉巖细卧,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件尉桩,死亡現(xiàn)場離奇詭異,居然都是意外死亡贪庙,警方通過查閱死者的電腦和手機(jī)蜘犁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來止邮,“玉大人这橙,你說我怎么就攤上這事〉寂” “怎么了屈扎?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長撩匕。 經(jīng)常有香客問我鹰晨,道長,這世上最難降的妖魔是什么止毕? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任模蜡,我火速辦了婚禮,結(jié)果婚禮上扁凛,老公的妹妹穿的比我還像新娘哩牍。我一直安慰自己,他們只是感情好令漂,可當(dāng)我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著丸边,像睡著了一般叠必。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上妹窖,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天纬朝,我揣著相機(jī)與錄音,去河邊找鬼骄呼。 笑死共苛,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蜓萄。 我是一名探鬼主播隅茎,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼嫉沽!你這毒婦竟也來了辟犀?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤绸硕,失蹤者是張志新(化名)和其女友劉穎堂竟,沒想到半個月后魂毁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡出嘹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年席楚,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片税稼。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡烦秩,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出娶聘,到底是詐尸還是另有隱情闻镶,我是刑警寧澤,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布丸升,位于F島的核電站铆农,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏狡耻。R本人自食惡果不足惜墩剖,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望夷狰。 院中可真熱鬧岭皂,春花似錦、人聲如沸沼头。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽进倍。三九已至土至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間猾昆,已是汗流浹背陶因。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留垂蜗,地道東北人楷扬。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像贴见,于是被迫代替她去往敵國和親烘苹。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內(nèi)容