【C语言】结构体类型的定义与使用
目錄
一、結(jié)構(gòu)體
二、結(jié)構(gòu)體的定義
1.最基本的定義
2.有 typedef 的定義
3.定義即對象方式
4.定義即對象指針方式(涉及指針就會稍微復(fù)雜一點)
5. typedef結(jié)構(gòu)體和結(jié)構(gòu)體指針方式
三、結(jié)構(gòu)體的使用
一、結(jié)構(gòu)體
? ? ? ? 結(jié)構(gòu)體是用戶自定義的一種類型,這種類型里面可以聲明不同的數(shù)據(jù)類型,如char、int...等等,以此來滿足用戶對某種對象的數(shù)據(jù)描述。比如我想描述某個人的職業(yè)信息,那么通過描述他的姓名(char name[ ]),年齡(int),職業(yè)(char position[ ]),業(yè)績(char),年薪( int )等就可以很清楚的知道這個的人的職業(yè)信息,當(dāng)我需要把這個人的職業(yè)信息發(fā)給親戚,總不能一句句發(fā),而是全部整合到一起發(fā),那么將多種數(shù)據(jù)類型整合到一起,我們可以使用結(jié)構(gòu)體類型。
二、結(jié)構(gòu)體的定義
? ? ? 結(jié)構(gòu)體定義的方式有很多種:
1.最基本的定義
struct Person {char name[16];int age; };? ? ? ? 此定義,定義了一個Person結(jié)構(gòu)體(記住是Person結(jié)構(gòu)體,而不是叫結(jié)構(gòu)體Person),意味著 struct Person才是結(jié)構(gòu)體類型,struct叫做關(guān)鍵字,Person叫做標(biāo)識符。因此,我們在使用的時候就得這樣使用:
struct Person john;這個Person結(jié)構(gòu)體聲明了一個對象,叫做 john。那么我們的某些編譯器為了讓我們節(jié)省打字壓力,允許我們省略 struct 關(guān)鍵字:
Person john;ps:這里Person沒有變色是因為我們的結(jié)構(gòu)體定義沒有寫進去,就寫了一個聲明對象。不是因為這種聲明方式不可以哈(我的編譯器是支持這種寫法的)。但是這種寫法在理論上來說是錯誤的(世上本沒有路,走的人多了也就變成了路),如定義所說,這Person只是描述符,只有struct Person這種才代表了結(jié)構(gòu)體類型,所以這種聲明方式可以但不推薦大家這樣寫,以免對結(jié)構(gòu)體定義有所混淆,那么如何正確省略struct這個關(guān)鍵字,看下面第2種定義。
2.有 typedef 的定義
typedef struct Person {char name[16];int age; }per;????????這里的定義,用口語正確表達是:首先定義了一個struct Person的結(jié)構(gòu)體,然后 typedef 關(guān)鍵字(這個關(guān)鍵字叫別定義)將 struct Person 別定義為 per。也就是說現(xiàn)在 per 就等價于 struct Person。那么就有如下聲明:
per john;? ? ? ? 這樣才是正確省略struct的方式。那么可以看出,用了 typedef 之后:
struct Person john;//正確,最原始的聲明per john;//正確,typedef的聲明 struct per john;//錯誤,per = struct Person3.定義即對象方式
struct Person {char name[];int age; }per;? ? ? ? 這種沒有使用typedef的定義方式,叫定義即對象,也就是per就是struct Person的對象,相當(dāng)于第2條中的 john。對于這種直接定義了對象的,可以重新使用如下聲明第二個對象,也可以直接使用對象per:
struct Person john;//聲明對象john? ? ? ? 那么這里的per,也是對象,是可以直接使用的,無需再重復(fù)聲明了,如下使用
struct Person {char name[16];int age; }per;int main() {strcpy(per.name, "xiaoming");per.age = 16;printf("%s\n", per.name);printf("%d\n", per.age);return 0; }4.定義即對象指針方式(涉及指針就會稍微復(fù)雜一點)
struct Person {char name[16];int age; }*per;int main() {per = (Person*)malloc(sizeof(struct Person));strcpy(per->name, "xiaoming");per->age = 16;printf("%s\n", per->name);printf("%d\n", per->age);free(per);return 0; }? ? ? ? 這種定義方式,和第3條有點類似,都是直接定義了Person結(jié)構(gòu)體的對象,不過現(xiàn)在這個對象是個指針,所以per我們稱為結(jié)構(gòu)體指針。
? ? ? ? 如果在定義時就聲明了結(jié)構(gòu)體指針,這指針是全局變量,存儲在靜態(tài)區(qū),在整個程序結(jié)束后才會釋放 *per 的內(nèi)存(當(dāng)然,要明白這個內(nèi)存是存儲的是 指針?本身即指針的地址,而不是數(shù)據(jù)成員name和age,現(xiàn)在這個指針的地址用了變量per表示, 這個 指針的變量per 的內(nèi)容(值)是另一塊內(nèi)存的地址,即數(shù)據(jù)成員的首地址)。
? ? ? ? 其次,在其他函數(shù)中(如main函數(shù))欲使用 指針per 指向的數(shù)據(jù)成員,需要為數(shù)據(jù)成員開辟內(nèi)存空間,使用malloc函數(shù)。這樣 指針per(*per)指向的內(nèi)存(數(shù)據(jù)成員的內(nèi)存)就是存儲在 堆 上,而非 棧(只存儲局部變量) 上,也不是靜態(tài)區(qū)(只存儲靜態(tài)變量和全局變量)。在使用完畢后,需要使用 free函數(shù) 手動釋放存儲在 堆 上的數(shù)據(jù)成員的內(nèi)存空間。
5. typedef結(jié)構(gòu)體和結(jié)構(gòu)體指針方式
typedef struct Person {char name[16];int age; }per, *perptr;int main() {per a;a.age = 16;printf("%d\n", a.age);perptr v;v = (Person *)malloc(sizeof(struct Person));v->age = 14;printf("%d\n", v->age);free(v);return 0; }? ? ? ? 看到這里,你就需要明白,既然用了typedef關(guān)鍵字,就代表 per 等價于 struct Person,*perptr 等價于 struct Person*(好好理解有typedef和沒有typedef的區(qū)別,一個是結(jié)構(gòu)體指針,一個是結(jié)構(gòu)體對象指針)。既然是結(jié)構(gòu)體指針,那么首先肯定要聲明一個對象, perptr v;
三、結(jié)構(gòu)體的使用
? ? ? ? 結(jié)構(gòu)體的使用其實在第二個里面有略微介紹到:主要就兩種結(jié)構(gòu)體和結(jié)構(gòu)體指針的使用
typedef struct Base {int a; }base;int main() {//1.結(jié)構(gòu)體base A;A.a = 11;printf("%d\n", A.a);//2.結(jié)構(gòu)體指針base* B;B = (base*)malloc(sizeof(base));B->a = 12;printf("%d\n", B->a);free(B);//2.結(jié)構(gòu)體賦值給結(jié)構(gòu)體指針,即這個結(jié)構(gòu)體指針指向另一個結(jié)構(gòu)體 base* C;C = &A;printf("%d\n", C->a);return 0; }? ? ? ? 那么結(jié)構(gòu)體到此最基本的知識就已經(jīng)講完了------。
總結(jié)
以上是生活随笔為你收集整理的【C语言】结构体类型的定义与使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网卡用来实现计算机和什么之间的物理链接,
- 下一篇: 【嵌入式单元测试】C语言单元测试框架搭建