標籤:
0內容簡介1、課程大綱2、第二部分第六課: 建立你自己的變數類型3、第二部分第七課預告: 檔案讀寫課程大綱我們的課程分為四大部分,每一個部分結束後都會有練習題,並會公布答案。還會帶大家用C語言編寫三個遊戲。C語言編程基礎知識什麼是編程?工欲善其事,必先利其器你的第一個程式變數的世界運算那點事條件運算式迴圈語句實戰:第一個C語言小遊戲函數練習題習作:完善第一個C語言小遊戲C語言進階技術模組化編程進擊的指標,C語言王牌數組字串預先處理建立你自己的變數類型檔案讀寫動態分配實戰:“懸掛小人”遊戲安全的文本輸入練習題習作:用自己的語言解釋指標用基於C語言的SDL庫開發2D遊戲安裝SDL建立視窗和畫布顯示映像事件處理實戰:“超級瑪麗推箱子”遊戲掌握時間的使用用SDL_ttf編輯文字用FMOD控制聲音實戰:可視化的聲音譜線練習題資料結構鏈表堆,棧和隊列雜湊表練習題第二部分第六課:建立你自己的變數類型眾所周知,C語言是面向過程的程式設計語言,與Java,C#等物件導向的程式設計語言有所不同。在物件導向的程式設計語言中,有類的概念。C語言是沒有類這種“類型”的,但是C語言就不能類比“物件導向”編程了嗎?不,只要你設計得好,C語言也可以類比物件導向編程。這一課我們學到的關於struct(結構體)的知識就可以使你有能力用C語言實現物件導向。前面我們學習了指標,數組,字串和預先處理,掌握這些知識你的C語言水平已經還不錯啦,但是我們豈能就此止步。C語言還可以讓我們做一些更厲害的事情:建立你自己的變數類型。我們可以將其稱為“自訂的變數類型”,我們來看三種:struct,union和enum。因為當你需要編寫的程式比較複雜的時候,你會發現建立自訂的變數類型是很重要的。幸好,這學起來其實也不是特別難。但是大家需要專心學習這一課,因為從下一課開始,我們會一直用到struct了。定義一個struct什麼是struct呢,首先它是英語structure(結構)的簡寫。所以struct的專業術語是“結構體”。定義:struct就是一系列變數的集合,但是這些變數可以是不同類型的。這個定義是不是喚起了大家對我們的老朋友:數組的懷念啊。數組裡面的每個成員都必須是同一個類型的,相比之下struct更靈活。一般來說,我們習慣把struct定義在.h標頭檔中,也就是和預先處理命令以及函數原型那群傢伙在一起。下面就給出一個struct的例子:struct 你的struct的名字{char variable1;short variable2;int otherVariable;double numberDecimal;};可以看到:struct的定義以關鍵字struct開始,後面接你自訂的struct的名稱(比如 Dog,Cat,Person等)。一般來說,在My Code裡,我的struct的命名也是遵照變數的命名規則,唯有一點不一樣,就是struct的名稱我會將首字母大寫,例如:SchoolName。但是我的普通變數一般都是首字母小寫,例如:studentNumber。這樣做只是個人習慣,便於在代碼裡區分普通的變數和自訂的變數,之後會學到的enum和union,我也是習慣將其名稱的首字母大寫。在struct的名字之後,我們需要寫上一對大括弧,在這對大括弧裡面放你的struct要包含的各種類型的變數。通常說來,struct的大括弧內至少得定義兩個變數吧,如果只有一個變數,那定義這個結構體也沒什麼意義。注意:特別不要忘了,在大括弧後面還要加上一個分號; 因為畢竟這個struct是一個變數,變數的定義最後都要加分號的。如你所見,建立一個自訂的變數也不複雜麼。其實結構體就是各種基本類型變數的集合,一個大雜燴。當然以後的課程中我們還會看到:結構體的嵌套定義(結構體裡包含另一個結構體)。結構體的例子假設我們需要自訂一個結構體,它儲存螢幕上的一個點的座標。在之後第三部分“用C語言編寫遊戲”裡面,會用到類似的結構。下面就給出2D(D是英語dimension的首字母,表示維度)世界的座標系的大致印象:0當我們在2D世界中做研究時,我們有兩個軸:橫座標軸(從左至右,一般也稱為x軸)和垂直軸(從下到上,一般也稱為y軸)。只要數學還沒有還給小學化學老師,應該都知道x和y軸的。現在,你自己可以寫出一個名叫Coordinate(英語“座標”的意思)的struct的定義了嗎?我看好你!可以自己先寫,然後對一下我們給出的參考:struct Coordinate{int x; // 橫座標int y; // 縱座標};我們的Coordinate這個struct包含了兩個變數:x和y,都是int類型,分別表示橫座標值和縱座標值。當然了,如果我們願意,也可以建立一個表示3D(三維)空間的點的struct,只需要在剛才的Coordinate這個結構體的基礎上加上z軸。結構體裡面的數組結構體裡面也可以存放數組。可以構造一個名叫Person(英語“人”的意思)的結構體,如下所示:struct Person{char firstName[100]; // 名char lastName[100]; // 姓char address[1000]; // 地址int age; // 年齡int boy; // 布爾值 : 1 = boy(男孩), 0 = girl(女孩)};可以看到,這個結構體變數包含五個基本的變數。前三個分別表示 名,姓和地址,是字元數組。第四個是年齡,第五個是一個“布爾值”(當然,C語言本身沒有定義布爾類型(true或false),但是可以用數值來“表示”布爾值的真或假),boy這個int變數的值如果為1,那就是表示男孩,如果為0,那就是女孩。這個結構體可以用於構建一個通訊錄程式。當然,你大可以在這個結構體裡再添加其他變數,使其更完善。在一個結構體裡沒有變數的數目限制。結構體的使用現在,我們的結構體已經定義在.h標頭檔裡了,那麼我們就可以在include(包含)此標頭檔的檔案中使用這些結構體了。以下展示如何建立一個類型為Coordinate(此結構體我們上面定義了,表示二維空間的座標)的變數:#include "main.h" // 包含定義結構體的標頭檔int main(int argc, char *argv[]){struct Coordinate point; // 建立一個Coordinate類型的變數,名字是point(英語“點”的意思)return 0;}如上,我們建立了一個Coordinate類型的變數,名字是point。這個變數自動擁有兩個子變數:x和y,都是int類型,分別表示此二維座標的橫座標值和縱座標值。你也許要問:“建立結構體變數開頭的那個關鍵字struct是必須的嗎?”是的,必須的。“愛我,非你莫屬...”不好意思又跑題了。。。struct關鍵字使電腦能夠區分基礎變數類型(例如int)和自訂變數類型(例如Coordinate)。然而,每次加struct關鍵字也有點麻煩,所以聰(懶)明(惰)伶(成)俐(性)的C語言開發人員們設計了typedef關鍵字。當然了,人類的大多數發明都是為了“懶惰”的緣故,能提高效率誰不想啊。就是這個feel,倍爽兒。typedef關鍵字重新回到剛才定義Coordinate這個結構體的.h標頭檔中。我們來加一條由typedef開頭的命令,目的是為Coordinate結構體建立一個別名。什麼是別名呢?就是比如有一個人,真實姓名叫王小明,別名就可以是小明,明明,等,但都代表那個人。有點類似C++的引用的機制。所以對別名的操作就是對原先對象的操作。我們就在Coordinate結構體的定義之前加這句命令吧,一般習慣加在後面的,但是加在前面也可以:typedef struct Coordinate Coordinate;struct Coordinate{int x;int y;};可以看到,我們新加了一行命令:typedef struct Coordinate Coordinate;為了更好地理解這句命令的作用,我們把它拆為三部分來看:1. typedef:說明我們將要建立一個別名2. struct Coordinate:這是我們要為其建立別名的結構體3. Coordinate:這就是別名所以,上面這句命令的含義就是“從今以後,Coordinate就相當於struct Coordinate”。這樣做以後,我們就可以不用每次在建立一個新的Coordinate結構體的變數時都加上struct關鍵字了。所以,我們的.c檔案中就可以改寫為:int main(int argc, char *argv[]){Coordonnees point; // 因為有了typedef,電腦就清楚地知道此處的Coordinate其實就是“struct Coordinate”return 0;}當然,不一定要都叫Coordinate,別名也可以叫:Coor。例如:typedef struct Coordinate Coor;struct Coordinate{int x;int y;};Coor coor; // 建立一個變數建議大家在平時定義了struct類型後,也加一句typdedef命令,這樣在代碼裡就不用每次建立一個此類型的變數時都要在開頭寫struct關鍵字了。很多程式員都會這麼做。因為一個好的程式員是懂得如何偷懶的程式員,這和一個懶惰的程式員是有區別的。我們要使我們的代碼“write less,do more”(用盡量少的代碼做更多的事)。當然,上面的代碼塊可以簡寫為:typedef struct 名字{// struct的內容} 別名;所以上面Coordinate的代碼塊可以簡寫為:typedef struct Coordinate{int x;int y;} Coordinate;注意:之後我們的範例程式碼,有時會出現例如Person player1;Coordinate point1;這樣的形式,那就是假定我們之前已經用了typedef了:typedef struct Person Person;就可以省略開頭的struct關鍵字,不需要再寫成:struct Person player1;修改struct的成員變數既然我們的point變數(是Coordinate類型的,希望大家還沒暈)已經建立好了,那我們就可以修改它的成員的值了。我們如何訪問point的兩個成員x和y呢?如下所示:int main(int argc, char *argv[]){Coordinate point;point.x = 10;point.y = 20;return 0;}這樣,我們就順利地修改了point的兩個成員的值,使其x座標為10,y座標為20。因此我們的點就位於座標系的(10,20)處了。所以,為了能訪問到結構體的某個成員,我們可以這樣做:結構體執行個體名稱.成員名中間的點(.)表示“從屬”關係。如果有物件導向編程基礎的朋友,就會覺得:這與“類和對象”也太像了吧,是的,其實我們可以用struct來“類比”類。如果我們用上面我們建立的Person這個結構體來舉例子的話:int main(int argc, char *argv[]){Person user; // user是英語“使用者”的意思printf("您姓什麼 ? ");scanf("%s", user.lastName);printf("您名叫什麼 ? ");scanf("%s", user.firstName);printf("原來你的名字是 %s%s,失敬失敬\n", user.lastName, user.firstName);return 0;}運行輸出:您姓什嗎?王您名叫什嗎?小明原來您的名字是 王小明,失敬失敬。我們把user.lastName傳給scanf,使得使用者輸入的值直接修改user的lastName成員;我們對user.firstName也是如此。當然我們也可以再添加對address,age,boy的賦值。但是小編懶,就不繼續啦。做程式員就是要會偷懶。當然了,你也許會說:“我不知道結構體的使用,我用兩個單獨的字串變數lastName和firstName不是也可以做到和上述程式相同的事嗎?”是的,但是用結構體的好處就是我們可以建立此結構體的變數,將很多相關聯的資料封裝在一起,成為一個整體,而不是零散地定義。比如定義了Person這個結構體之後,凡是用Person來建立的變數,裡面都自動包含了 lastName,firstName,address,age和boy這五個變數,非常方便。比如我們可以這樣建立:Person player1, player2; //之前肯定有用typedef,( typedef struct Person Person;)在player1和player2中都包含lastName,firstName,address,age和boy這五個變數。我們也可以更“偷懶”一些:建立結構體數組。例如:Person player[2];這樣,我們就可以很方便的訪問player[1]當中的變數了,例如:player[1].lastName = "xiaoming";用結構體數組的好處是可以方便地使用迴圈,等等。自測小練習:建立一個名叫ProgrammerLeague(程式員聯盟)的結構體,在定義裡放入你想建立的變數。然後建立此結構體的一個數組,用迴圈的方式給變數賦值,再用迴圈的方式列印出其中變數的資訊。結構體的初始化之前的課程裡,我們建議對於基本變數,數組和指標,最好在建立的時候對其初始化。結構體也不例外。初始化有一個很大的好處,就是避免此變數裡存放“任意資料”。事實上,一個變數在建立時,如果沒有初始化,它會取當時在記憶體那個位置所存的值,所以這個值的隨機性是很大的。我們來回憶一下,不同變數的初始化應該怎麼做:基礎變數(int,double,char等):初始化為0指標:初始化為NULL。事實上,NULL位於stdlib.h標準庫標頭檔中,是用#define預先處理命令定義的一個常量。它的值通常是0。雖然是0,但是有多種定義形式,例如:#define NULL 0#define NULL 0L#define NULL ((void *) 0)但是我們只要每次用NULL就好了,為了清楚表明這是指標變數,而不是一般變數。數組:將每一個成員變數初始化為0對於我們的朋友:結構體,我們怎麼初始化呢?其實結構體的初始化也很簡單,與數組的初始化很類似。我們可以像下面這樣定義:Coordinate point = {0, 0};這樣,我們就依照順序將point.x和point.y都初始化為0了。對於像Person這樣的結構體,裡面的變數類型有 char型數組和int,那麼我們可以將char型數組初始化為""(雙引號中間為空白)。我們可以像這樣初始化一個字串,在之前“字串”那一課忘記提了。不過,我想現在提還不算晚吧。所以我們就可以這樣來初始化我們的Person結構體變數:Person player = {"", "", "", 0, 0};然而,我們也可以這樣來初始化一個結構體變數。建立一個函數,比如叫initializeStruct,可以為每一個傳遞給它的結構體做初始化,這樣就方便很多,特別是當結構體中的變數很多時。之前指標那一章我們也已經學了,如果我們對函數傳遞普通變數,那麼因為C語言的函數參數傳遞方式是值傳遞,所以它會對傳給它的函數參數做一份拷貝,所以函數裡面修改的其實是那一份拷貝,真正的實參並沒有被改變。為了讓實參實實在在被修改,我們需要用到指標,也就是傳遞此變數的地址。對於結構體,也需要這樣。因此,接下來我們就來學習如何使用結構體指標。開始要有點難咯。準備好了嗎?結構體指標結構體指標的建立其實和普通的指標變數建立沒什麼區別。例如:Coordinate *point = NULL;上面的代碼就建立了一個叫做point的Coordinate結構體指標變數(Coordinate是我們上面定義的表示座標的一個結構體)。我們再來提醒一次:一般推薦寫成:Coordinate *point = NULL; // 星號挨著指標變數名字而不推薦寫成:Coordinate* point = NULL; // 星號挨著結構體名在指標的建立中,我們推薦第一種寫法,因為如果用第二種寫法,如果你在一行上建立好幾個指標變數時,會容易忘記在第二個之後的變數前加*號。例如,容易寫成這樣:Coordinate* point1 = NULL, point2 = NULL;但這樣編譯會出錯,因為point2其實是Coordinate結構體變數,而不是Coordinate結構體指標變數!所以我們建議這樣寫:Coordinate *point1 = NULL, *point2 = NULL;在以前的課程中,對於基礎類型的指標變數,我們也是這樣建議:int *number1 = NULL, *number2 = NULL;特別是int型的指標,還很不容易察覺到錯誤,如果寫成:int* number1 = NULL, number2 = NULL;編譯器是不會報錯的。因為NULL的值就是0,可以賦給number2這個int型變數(注意:上面的number2不是int指標)。好吧,回顧總是很好的,(傷心總是難免的...)。結構體作為函數參數這裡,我們主要來學習如何將一個結構體指標(為什麼是傳結構體指標而不是傳結構體,可以看之前的解釋)傳給一個函數(作為參數),使得函數內部可以真正修改此結構體。我們來看一個執行個體:#include typedef struct Coordinate // Coordinate是英語“座標”的意思{ int x; // 橫座標值 int y; // 縱座標值} Coordinate;void initializeStruct(Coordinate *point); // 函數原型int main(int argc, char *argv[]){ Coordinate myPoint; initializeCoordinate(&myPoint); return 0;}// 用於初始化結構體變數void initializeCoordinate(Coordinate *point){ // 放置結構體初始化的代碼}上面的initializeCoordinate函數體內,我們將放置初始化結構體的成員變數的代碼。我們按順序來看一下這段代碼:首先,我們定義了一個結構體,叫做Coordinate,裡麵包含兩個變數,x和y。我們在main函數中建立了Coordinate結構體的變數,名字叫myPoint。我們將myPoint的地址傳遞給initializeCoordinate這個函數。接下來,我們就在initializeCoordinate函數中添加初始化x和y變數的代碼吧:void initializeCoordinate(Coordinate *point){ *point.x = 0; *point.y = 0;}point前面的*號是不可以少的噢,因為,傳進函數的參數是一個結構體指標,我們要取到此結構體,就需要用到“解引用”符號:*號。但是,認真的讀者看出上面這個函數中的錯誤了嗎?我們的初衷是想要:先用*號解引用point這個結構體指標,取到結構體,然後再用.號取到其中的變數x和y。但是如果按上面的寫法,其實效果相當於如下:*(point.x) = 0;*(point.y) = 0;因為.號的優先順序是高於*號的。有興趣可以看一下運算子的優先順序,不過之前的課我們也說過了,記不清怎麼辦呢?加括弧就解決啦。上面的代碼編譯是通不過的,因為結構體指標point並沒有成員叫x和y,而且,對於結構體指標我們也不能用.號來取到什麼值。因此,我們需要修改一下。改為如下就可以了:void initializeCoordinate(Coordinate *point){ (*point).x = 0; (*point).y = 0;}這樣就對了。用括弧去掉了運算子優先順序的影響。但是,之前也說過:程式員是懂得偷懶的一群人。如果每次要取結構體的成員變數都要這麼麻煩,要用*號,還要加括弧,再用.號。想想都要讓Denis Ritchie老爺子醉了。他是決不允許這種事發生的,因此,他就定義了一個新的符號: -> 用法如下:point->x = 0;就相當於:(*point).x = 0;是不是簡便了很多?記住:這個符號,只能用在指標上面。因此,我們的函數可以改寫為:void initializeCoordinate(Coordinate *point){ point->x = 0; point->y = 0;}我們在main函數裡也可以這樣寫:int main(int argc, char *argv[]){ Coordinate myPoint; Coordinate *myPointPointer = &myPoint; myPoint.x = 10; // 用結構體的方式,修改myPoint中的x值 myPointPointer->y = 15; // 用結構體指標的方式,修改myPoint中的y值 return 0;}結構體是C語言中一個非常好用,很重要的概念,希望大家好好掌握,當然還有不少知識細節就要大家自己去看C語言的經典教材了,例如《C程式設計語言》(不是譚浩強那本《C語言程式設計》),《C和指標》,《C專家編程》,《C語言深度解剖》,《C陷阱和缺陷》,等等。unionunion是術語“聯合”的意思,是C語言的關鍵字,也有的書上翻譯為“共用體”。我們可以來寫一個union的例子。union ProgrammerLeague{char character;int memberNumber;double rate;};乍看之下,簡直和struct沒什麼區別麼。但是真的沒有區別嗎?假如我們用sizeof關鍵字來測試此union的大小(大小指的是其在記憶體中所佔的位元組(byte)數,一個位元組相當於8個bit(二進位位)):#include typedef union ProgrammerLeague{ char character; // 大小是1 int memberNumber; // 大小是4 double rate; // 大小是8} ProgrammerLeague;int main(int argc, char *argv[]){ ProgrammerLeague programmerLeague; printf("此聯合的大小是 %lu\n", sizeof(programmerLeague)); return 0;}運行程式,輸出:此Union的大小是 8假如我們對結構體也做一次測試,對比一下:#include typedef struct ProgrammerLeague{ char character; // 大小是1 int memberNumber; // 大小是4 double rate; // 大小是8} ProgrammerLeague;int main(int argc, char *argv[]){ ProgrammerLeague programmerLeague; printf("此結構體的大小是 %lu\n", sizeof(programmerLeague)); return 0;}運行程式,輸出:此Structure的大小是 16為什麼一個是8,而另一個是16呢?這就涉及到union(共用體)和struct(結構體)的區別了。struct的大小是其中所有變數大小的總和,但是你會說:“不對啊, 1+4+8 = 13,為什麼sizeof(programmerLeague)的值為16呢?”好問題!這個有點複雜,涉及到記憶體對齊的問題,我們以後再說。或者有興趣的讀者可以去參考《C語言深度解剖》(網上可以搜到PDF)的解釋。一般初學C語言不需要太深究這個問題。在嵌入式編程等記憶體有限的環境下,需要考慮記憶體對齊,以節省空間的。union的大小等於其中最大(sizeof()最大)的那個變數的大小。所以我們就知道了,其實union的儲存是這樣的:其中的每個變數在記憶體中的起始地址是一樣的,所以union同一時刻只能存放其中一個變數,所以union的大小等於其中最大的那個變數,以保證可以容納隨便哪個成員。union適合用在很多相同類型的變數集,但是某一時刻只需用到其中一個的情況,比較節省空間的。enum看完了struct(結構體)和union(聯合),我們最後來學習很常用的一個自訂變數類型:enum。enum是英語enumeration(枚舉)的縮寫,也是一個C語言關鍵字。枚舉是一個比較特別的自訂變數類型。當初學C語言時,一開始還真有點不理解。但用好了,卻非常實用。我們之前學了:結構體裡麵包含了多個可以是不同類型的成員變數(一說“成員”就有點物件導向的感覺 :P。咬字要清晰,不是“淳元”皇后那個鄭淳元,是成員。小編你這樣頑皮可不行啊...)。但是enum(枚舉)裡面是一系列可選擇的值。也就是說每次只能取其中一個值,聽著和union有點類似啊。但是和union還是有區別的。我們來舉一個例子就知道區別了:typedef enum Shape Shape;enum Shape // shape是英語“身材、體型”的意思{ THIN, // thin是英語“瘦”的意思 MEDIUM, // medium是英語“中等”的意思 FAT // fat是英語“胖”的意思};所以,我們定義了一個名叫 Shape的enum變數。其中有三個值,分別是THIN, MEDIUM和FAT(身材有瘦,中等和胖之分)。不一定要大寫,只是習慣。那我們怎麼來建立enum變數呢?如下:Shape shape = MEDIUM;shape這個變數,我們在程式裡,也可以再將其修改為 THIN或者FAT。將數值賦給enum的成員大家看到enum和union以及struct的區別了嗎?是的,enum的定義裡,每個成員沒有變數類型(int,char,double之類)!很奇怪吧。想起來為什麼enum的成員習慣用大寫了嗎?對,就是因為enum的每個成員都不是變數,而是常量。但是enum的機制和常量定義以及#define還是有些區別:像上面的代碼:typedef enum Shape{ THIN, MEDIUM, FAT } Shape;編譯器會自動為其中的每一個成員綁定一個常量值,我們寫程式測試一下:#include typedef enum Shape Shape;enum Shape{ THIN, MEDIUM, FAT};int main(int argc, char *argv[]){ Shape shape = THIN; printf("THIN = %d\n", shape); shape = MEDIUM; printf("MEDIUM = %d\n", shape); shape = FAT; printf("FAT = %d\n", shape); return 0;}運行程式,輸出:THIN = 0MEDIUM = 1FAT = 2看到了嗎?編譯器自動給這三個成員賦了 0,1和2。如果沒有指定enum成員的值,那麼它們的值是從0開始,依次加1。我們也可以自己來定義enum成員的值,不一定要每次讓編譯器給我們自動分配。我們可以這樣寫:typedef enum Shape{ THIN = 40, MEDIUM = 60, FAT = 90} Shape;這樣,我們就自己給每個成員定義了值。我們也可以讓編譯器為我們自動分配幾個值,再自己定義幾個值,例如:typedef enum Shape{ THIN, MEDIUM, FAT = 90} Shape;上面,我們沒有為THIN和MEDIUM賦值,那麼編譯器會給他們賦值為0和1,而FAT,因為我們已經指定了其值為90,所以FAT就等於90。enum和#define的區別是不是覺得enum和用#define來定義的常量是有些類似呢?其實,還是有些不同的:#define 宏常量(或 預先處理常量)是在預先處理階段進行簡單替換,枚舉常量則是在編譯的時候確定其值。一般在編譯器裡,可以調試枚舉常量,但是不能調試宏常量。枚舉可以一次定義大量相關的常量,而#define 宏一次只能定義一個。總結結構體(struct)是一種自訂的變數類型,完全由我們自由發揮,自己定製。與int,double等基礎變數類型有所區別。結構體的使用可以使我們的C語言程式更加靈活,可以做更多事。結構體裡包含成員變數,通常是基礎變數類型的變數,如int,double等變數,但也可以有指標變數,數組,甚至其他的結構體變數。為了訪問到結構體的成員變數,我們可以用普通的結構體方式訪問:結構體變數名稱.成員變數名我們也可以用特別簡便的結構體指標的方式來方位我們的結構體的成員變數:結構體指標變數名->成員變數名union(“共用體”,或“聯合”)和struct的最大不同就是:union的大小是其中容量最大的那個成員變數的大小,而結構體的大小是每一個成員變數的總和(還要考慮記憶體對齊),union一次只能取其中一個變數。enum(枚舉)一次只能取其中的一個成員的值,這一點和union有些類似,但是enum的成員都是常量,而不是變數。而且enum的成員如果沒有指定數值,編譯器會按照遞增順序為每一個變數賦值,從0開始。第二部分第七課預告:今天的課就到這裡,一起加油咯。下一次我們學習:檔案讀寫程式員聯盟社區目前有一個群和一個QQ群(群120人以上,QQ群250人以上),凡是對編程感興趣的朋友都可以加,大家可以交流,學習,互動,討論寫的程式的原始碼,編程問答等。手機上裡的二維碼圖片如何“掃描”呢?小竅門:在裡長按圖片,選擇“識別圖中二維碼”,就可以了群(程式員聯盟),加群請私信我(群人數超過100之後,不能通過掃描二維碼加入了,只能私信我,謝謝)QQ群(程式員聯盟),群號是 413981577QQ群共用裡有N多編程PDF。掃描下面二維碼加QQ群:0我們還建立了一個公用的百度雲端硬碟,2TB容量,供大家上傳優秀編程資源,連結加群之後會發送。也建立了《程式員聯盟》的微社區,方便大家提問和互動。可以關注一下。微社區地址和二維碼如下:http://m.wsq.qq.com/2641521480謝謝!0程式員聯盟 公眾號*您若覺得本文不錯,請點擊畫面右上方《···》按鈕“分享到朋友圈”或“發送給朋友”*新朋友請關注「程式員聯盟」搜公眾號 ProgrammerLeague小編號: frogoscar小編QQ號: 379641629小編郵箱: [email protected]程式員聯盟QQ群:413981577程式員聯盟群:先加我有朋友反映看手機端的文章太累,其實是可以用瀏覽器網頁來看的方法1. 點擊畫面右上方的《···》按鈕,然後選擇“複製連結”,再把連結黏貼到你的瀏覽器裡面或用郵件發送給自己,就可以在電腦的瀏覽器裡開啟了0方法2. 頭條網www.toutiao.com,搜尋我的自媒體“程式員聯盟”,裡面有所有文章,也可以直接進這個連結:http://www.toutiao.com/m3750422747/方法3. 我的51CTO部落格和CSDN部落格連結(所有文章會在上面)http://4526621.blog.51cto.com/http://blog.csdn.net/frogoscar新朋友如何查看所有文章: 點擊“查看公眾號”,再點擊“查看曆史訊息”00“程式員聯盟”公眾號專為程式員,App設計師,各位喜愛編程和熱愛分享的小夥伴們推送各樣編程相關知識,優秀軟體推薦,業界動態等。搜尋 ProgrammerLeague 加關注~點擊下方“附件”查看 Dennis Ritchie編著的《C程式設計語言》第二版中文版PDF ↓↓↓
【C語言探索之旅】 第二部分第六課:建立你自己的變數類型