IOS開發系列--C語言之構造類型

來源:互聯網
上載者:User

IOS開發系列--C語言之構造類型
概述在第一節中我們就提到C語言的構造類型,分為:數組、結構體、枚舉、共用體,當然前面數組的內容已經說了很多了,這一節將會重點說一下其他三種類型。 結構體枚舉共用體結構體數組中儲存的是一系列相同的資料類型,那麼如果想讓一個變數儲存不同的資料類型就要使用結構體,結構體定義類似於C++、C#、Java等進階語言中類的定義,但事實上它們又有著很大的區別。結構體是一種類型,並非一個變數,只是這種類型可以由其他C語言基本類型共同組成。 ////  main.c//  ConstructedType////  Created by Kenshin Cui on 14-7-18.//  Copyright (c) 2014年 Kenshin Cui. All rights reserved.// #include <stdio.h> //結構體類型Datestruct Date{    int year;    int month;    int day;}; struct Person{    char *name;    int age;    struct Date birthday;//一個結構體中使用了另一個結構體類型,結構體類型變數聲明前必須加上struct關鍵字    float height;}; int main(int argc, const char * argv[]) {    struct Person p={"Kenshin",28,{1986,8,8},1.72};    //定義結構體變數並初始化,不允許先定義再初始化,例如:struct Person p;p={"Kenshin",28,{1986,8,8},1.72};是錯誤的        printf("name=%s,age=%d,birthday=%d-%d-%d,height=%.2f\n",p.name,p.age,p.birthday.year,p.birthday.month,p.birthday.day,p.height);     //結果:name=Kenshin,age=28,birthday=1986-8-8,height=1.72,結構體的引用是通過"結構體變數.成員名稱"        printf("len(Date)=%lu,len(Person)=%lu\n",sizeof(struct Date),sizeof(struct Person));     //結果:len(Date)=12,len(Person)=32        return 0;}對於上面的例子需要做出如下說明: 可以在定義結構體類型的同時聲明結構體變數;如果定義結構體類型的同時聲明結構體變數,此時結構體名稱可以省略;定義結構體類型並不會分配記憶體,在定義結構體變數的時候才進行記憶體配置(同基本類型時類似的);結構體類型的所佔用記憶體大型等於所有成員佔用記憶體大小之和(如果不考慮記憶體對齊的前提下);對第4點需要進行說明,例如上面代碼是在64位編譯器下啟動並執行結果(int長度4,char長度1,float類型4),Date=4+4+4=12。但是對於Person卻沒有那麼簡單了,因為按照正常方式計算Person=8+4+12+4=28,但是從上面代碼中給出的結果是32,為什麼呢?這裡不得不引入一個概念“記憶體對齊”,關於記憶體對齊的概念在這裡不做詳細說明,大家需要瞭解的是:在Mac OS X中對齊參數預設為8(可以通過在代碼中添加#pragma pack(8)改變對齊參數),如果結構體中的類型不大於8,那麼結構體長度就是其成員類型之和,但是如果成員變數的長度大於這個對齊參數那麼得到的結果就不一定是各個成員變數之和了。Person類型的長度之所以是32,其實主要原因是因為Date類型長度12在儲存時其位移量12不是8的倍數,考慮到記憶體對齊的原因需要添加4個補齊長度,這裡使用表格的形式列出了具體原因: memoryAlign 表格具體來源請觀看下面的視頻(注意由於錄製軟體的原因前幾秒不清晰但是不影響分析):  接下來看一下結構體數組、指向結構體的指標: ////  main.c//  ConstructedType////  Created by Kenshin Cui on 14-7-18.//  Copyright (c) 2014年 Kenshin Cui. All rights reserved.// #include <stdio.h> struct Date{    int year;    int month;    int day;}; struct Person{    char *name;    int age;    struct Date birthday;    float height;}; void changeValue(struct Person person){    person.height=1.80;} int main(int argc, const char * argv[]) {    struct Person persons[]={        {"Kenshin",28,{1986,8,8},1.72},        {"Kaoru",27,{1987,8,8},1.60},        {"Rosa",29,{1985,8,8},1.60}    };    for (int i=0; i<3; ++i) {        printf("name=%s,age=%d,birthday=%d-%d-%d,height=%.2f\n",               persons[i].name,               persons[i].age,               persons[i].birthday.year,               persons[i].birthday.month,               persons[i].birthday.day,               persons[i].height);    }    /*輸出結果:     name=Kenshin,age=28,birthday=1986-8-8,height=1.72     name=Kaoru,age=27,birthday=1987-8-8,height=1.60     name=Rosa,age=29,birthday=1985-8-8,height=1.60     */                struct Person person=persons[0];    changeValue(person);    printf("name=%s,age=%d,birthday=%d-%d-%d,height=%.2f\n",           persons[0].name,           persons[0].age,           persons[0].birthday.year,           persons[0].birthday.month,           persons[0].birthday.day,           persons[0].height);    /*輸出結果:     name=Kenshin,age=28,birthday=1986-8-8,height=1.72     */            struct Person *p=&person;    printf("name=%s,age=%d,birthday=%d-%d-%d,height=%.2f\n",           (*p).name,           (*p).age,           (*p).birthday.year,           (*p).birthday.month,           (*p).birthday.day,           (*p).height);    /*輸出結果:     name=Kenshin,age=28,birthday=1986-8-8,height=1.72     */    printf("name=%s,age=%d,birthday=%d-%d-%d,height=%.2f\n",           p->name,           p->age,           p->birthday.year,           p->birthday.month,           p->birthday.day,           p->height);    /*輸出結果:     name=Kenshin,age=28,birthday=1986-8-8,height=1.72     */        return 0;}結構體作為函數參數傳遞的是成員的值(值傳遞而不是引用傳遞),對於結構體指標而言可以通過”->”操作符進行訪問。 枚舉枚舉類型是比較簡單的一種資料類型,事實上在C語言中枚舉類型是作為整形常量進行處理的,通常稱為“枚舉常量”。 ////  main.c//  ConstructedType////  Created by Kenshin Cui on 14-7-18.//  Copyright (c) 2014年 Kenshin Cui. All rights reserved.// #include <stdio.h> enum Season{ //預設情況下spring=0,summer=1,autumn=2,winter=3    spring,    summer,    autumn,    winter}; int main(int argc, const char * argv[]) {    enum Season season=summer; //枚舉賦值,等價於season=1    printf("summer=%d\n",season); //結果:summer=1        for(season=spring;season<=winter;++season){        printf("element value=%d\n",season);    }    /*結果:     element value=0     element value=1     element value=2     element value=3     */    return 0;}需要注意的是枚舉成員預設值從0開始,如果給其中一個成員賦值,其它後面的成員將依次賦值,例如上面如果summer手動指定為8,則autumn=9,winter=10,而sprint還是0。 共用體共用體又叫聯合,因為它的關鍵字是union(貌似資料庫操作經常使用這個關鍵字),它的使用不像枚舉和結構體那麼頻繁,但是作為C語言中的一種資料類型我們也有必要弄清它的用法。從前面的分析我們知道結構體的總長度等於所有成員的和(當然此時還可能遇到對齊問題),但是和結構體不同的是共用體所有成員共用一塊記憶體,順序從低地址開始存放,一次只能使用其中一個成員,union最終大小由共用體中最大的成員決定,對某一成員賦值可能會覆蓋另一個成員。 ////  main.c//  ConstructedType////  Created by Kenshin Cui on 14-7-20.//  Copyright (c) 2014年 Kenshin Cui. All rights reserved.// #include <stdio.h> union Type{    char a;    short int b;    int c;}; int main(int argc, const char * argv[]) {    union Type t;    t.a='a';    t.b=10;    t.c=65796;        printf("address(Type)=%x,address(t.a)=%x,address(t.b)=%x,address(t.c)=%x\n",&t,&t.a,&t.b,&t.c);    //結果:address(Type)=5fbff7b8,address(t.a)=5fbff7b8,address(t.b)=5fbff7b8,address(t.c)=5fbff7b8        printf("len(Type)=%d\n",sizeof(union Type));    //結果:len(Type)=4        printf("t.a=%d,t.b=%d,t.c=%d\n",t.a,t.b,t.c);    //結果:t.a=4,t.b=260,t.c=65796        return 0;}  這裡需要重點解釋一個問題:為什麼t.a、t.b、t.c輸出結果分別是4、260、65796,當然t.c等於65796並不奇怪,但是t.a前面賦值為’a’不應該是97嗎,而t.b不應該是10嗎?其實如果弄清這個問題共用體的概念基本就清楚了。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.