標籤:
------iOS培訓、Java培訓、Android培訓, iOS學習型技術部落格,期待與您交流------
C語言基礎---結構體
一、什麼是結構體
介紹結構體之前,我想先簡單介紹下數組。我想大家對數組都再熟悉不過了,顧名思義,數組就是將一些資料(元素)組合在一起,作為一個整體。使用數組需要注意的是這些元素必須是相同類型。而結構體和數組類似,也是將一些資料群組合在一起作為一個整體,但是這些元素可以是不同類型。可以這麼理解:結構體是更加靈活的數組,因為它允許元素是不同的類型。
實際生活中,如果我們要表達一個較為複雜的整體,在java中,我們定義一個類就可以了,因為java特性就是物件導向,然後定義各種屬性。但是C語言是面向過程的語言,如何表達一個較為複雜的整體呢?---就是用結構體。
二、結構體類型的定義:
因為結構體不是系統內建的資料類型,也不可能由系統內建,因為結構體是由程式員根據需要,自己定義的。因此,在定義結構體變數之前,首先要自訂相應的結構體類型。
結構體類型的定義形式:
struct 結構體類型名{
類型名1 成員名1;
類型名2 成員名2;
類型名3 成員名3;
...
};
其中struct是關鍵字。
例:
struct Book{
char *name; //書名
char *author; //書的作者
float price; //書的售價
};
上述代碼定義了一個叫做Book的結構體(註:定義結構體可以理解為告訴系統這個結構體有哪些成員,只是起到告訴系統的作用,此時並未分配記憶體空間),共有3個 成員,分別是:name、author、price。這個和java的物件導向有些許類似了。
三、結構體變數的定義:
上述代碼只是定義結構體類型,因為結構體類型不是系統內建,也不可能由系統定義,不像int、float、double、char這些基礎資料型別 (Elementary Data Type)可以由系統定義。結構體類型只能由程式員根據具體需求自己定義,因此結構體類型的定義只是告訴系統自己定義的結構體包括哪些成員而已,只是起到說明的作用,並沒有分配記憶體空間。如果要想使用該結構體,那麼就必須按照自訂的結構體類型為模板定義結構體變數,此時系統才會分配記憶體給結構體變數。
結構體變數定義形式:
1>先定義結構體類型,再定義結構體變數
//定義結構體類型
struct Book{
char *name; //書名
char *author; //書的作者
float price; //書的售價
};
struct Book book; //定義結構體變數,變數名為book。
2>定義結構體類型的同時定義結構體變數
struct Book{
char *name; //書名
char *author; //書的作者
float price; //書的售價
} book; //結構體變數名為book
3>直接定義結構體類型與變數,省略結構體類型名
struct {
char *name; //書名
char *author; //書的作者
float price; //書的售價
} book; //結構體變數名為book
註:定義結構體類型的時候系統並沒有分配記憶體空間,定義結構體變數的時候系統才分配記憶體空間。
四、結構體類型定義的注意點
1>結構體類型本身不能遞迴定義,即結構體類型的成員不允許是該結構體類型本身
//錯誤寫法
struct Book{
char *name; //書名
char *author; //書的作者
float price; //書的售價
struct Book book; //此行為錯誤寫法
};
2>結構體類型內部可以包含其他結構體類型
比如定義一本書的結構體類型,其成員包括書名、作者、售價、出版日期;但是出版日期也可以作為一個結構體類型,它的成員包括年、月、日。這種情況就是結構體包含其他結構體了。
struct PubDate{
int year;
int month;
int day;
}; //定義日期結構體類型,此時並未分配記憶體空間
struct Book{
char *name; //書名
char *author; //書的作者
float price; //書的售價
struct PubDate pubDate; //書的出版日期,結構體內包含另一種結構體
}; //定義書的結構體類型,此時並未分配記憶體空間
struct Book book; //定義結構體變數,變數名為book,此時系統分配記憶體空間給book變數。
結構體變數佔用的記憶體空間是其成員所佔記憶體空間之和,並且各成員在記憶體中按照定義的順序依次排列,
因此上面變數book在64位編譯器環境下共佔用記憶體為:8+8+4+4+4+4=32位元組 根據演算法,可能是36位元組
五、結構體的初始化
把結構體的各個成員的初始值按照定義的順序有序的放在{}中,用逗號分隔
例:
struct Book{
char *name; //書名
char *author; //書的作者
float price; //書的售價
};
struct Book book={“IOS開發指南”,“CF”,30.5}; //定義結構體變數並初始化,變數名為book。
註:只能在定義結構體變數的同時進行初始化賦值。
struct Book{
char *name; //書名
char *author; //書的作者
float price; //書的售價
};
//定義結構體變數和初始化賦值分開,錯誤
struct Book book;
book = {“IOS開發指南”,“CF”,30.5}; //錯誤
我們可以試想一下,將其與數組聯絡起來。定義數組的時候,數組名不能用來初始化賦值,因為數組名就是數組首元素的地址,也是數組地址,是個常量。既然數組名是常量,又怎麼可以進行初始化賦值呢?同理,結構體變數名也不行,故上述寫法錯誤。
六、如何使用自訂的結構體
對結構體變數的操作是以成員為單位,操作方式為: 結構體變數名.成員名
1>用點文法
“.”是成員運算子,在運算子中優先順序最高
例:
struct Book{
char *name; //書名
char *author; //書的作者
float price; //書的售價
};
struct Book book;
//訪問book的price成員,並賦值
book.price=55.5;
在結構體內部包含其他結構體的情況下,可以連續使用成員運算子“.”
例:
struct PubDate{
int year;
int month;
int day;
}; //定義日期結構體類型,此時並未分配記憶體空間
struct Book{
char *name; //書名
char *author; //書的作者
float price; //書的售價
struct PubDate pubDate; //書的出版日期,結構體內包含另一種結構體
}; //定義書的結構體類型,此時並未分配記憶體空間
struct Book book; //定義結構體變數,變數名為book,此時系統分配記憶體空間給book變數。
book.pubDate.year=2015;
book.pubDate.month=1;
book.pubDate.day=1;
以此類推,理論上可以使用無數個“.”進行所有成員的訪問。
七、結構體數組
什麼是結構體數組?顧名思義,數組的每一個元素都是一個結構體類型
1.結構體數組的定義方式:
//定義結構體陣列變數,變數名為book,元素個數為3
1> struct Book{
char *name; //書名
char *author; //書的作者
float price; //書的售價
};
struct Book book[3];
2> struct Book{
char *name; //書名
char *author; //書的作者
float price; //書的售價
} book[3];
3> struct {
char *name; //書名
char *author; //書的作者
float price; //書的售價
} book[3];
2.結構體數組的初始化,例:
struct Book{
char *name; //書名
char *author; //書的作者
float price; //書的售價
} book[3]={{"黑馬IOS基礎教程","CF",55.5},{"黑馬IOS進階教程","Peak",35.5},{"黑馬IOS快速入門","CF",35.5}};
利用數組的訪問方式(利用數組下標)訪問到數組的某個元素(是一個結構體),然後用成員運算子"."訪問該元素(結構體)的成員。
八、指向結構體的指標
學習要會觸類旁通,知道了C語言的指標,也知道了結構體,那麼理解指向結構體的指標也就不是什麼難事了。
我們知道,每個變數都有自己的記憶體位址,那麼結構體變數也不例外,既然有自己的記憶體位址,那麼就可以把地址賦值給指標變數,因此指標就可以指向該結構體變數了。
指向結構體的指標變數的定義形式:
struct 結構體類型名 *指標變數名;
那麼訪問結構體成員的方式就有三種:
1> 結構體變數名.成員名;
2> (*指標變數名).成員名;
3> 指標變數名->成員名;
例:
struct Book{
char *name; //書名
char *author; //作者
float price; //售價
} book={"黑馬IOS基礎教程","CF",55.5};
struct Book *p;
p=&book;
//三種訪問結構體成員的方式
printf("name=%s,author=%s,price=%f\n",book.name, book.author, book,price);
printf("name=%s,author=%s,price=%f\n",(*p).name, (*p).author, (*p).price);
printf("name=%s,author=%s,price=%f\n",p->name, p->author, p->price);
輸出結果為:
name=黑馬IOS基礎教程,author=CF,price=55.500000
name=黑馬IOS基礎教程,author=CF,price=55.500000
name=黑馬IOS基礎教程,author=CF,price=55.500000
黑馬程式員---C語言基礎---結構體