嵌入式第十天:結(jié)構(gòu)

今天來(lái)說(shuō)一下C語(yǔ)言里的結(jié)構(gòu)體(struct)线召、共用體(l聯(lián)合體)union翻翩、枚舉祷安。
歡迎加入嵌入式學(xué)習(xí)群:559601187

(一)結(jié)構(gòu)體:struct

1.1 概念

  • 是一種自定義的數(shù)據(jù)類型
  • 結(jié)構(gòu)體是構(gòu)造類型的一種
  • 不同數(shù)據(jù)類型的集合
  • 地址空間連續(xù)疼阔,每次分配最大數(shù)據(jù)類型的寬度
  • 占用內(nèi)存為所有變量的總大小(注意字節(jié)對(duì)齊問(wèn)題)

1.2 定義

1.先定義結(jié)構(gòu)體類型耗啦,再說(shuō)明結(jié)構(gòu)體變量

struct stu
{
    char *name;  //姓名
    int num;  //學(xué)號(hào)
    int age;  //年齡
    float score;  //成績(jī)
};
struct stu  student;

上面的程序使用strcuct關(guān)鍵字定義了一個(gè)結(jié)構(gòu)體名為stu的結(jié)構(gòu)體類型纫版。和定義變量一樣床绪,聲明一個(gè)結(jié)構(gòu)體類型變量可以使用:數(shù)據(jù)類型 變量名 的形式。
struct stu student表示定義了一個(gè)變量名為stduent其弊,類型為stu的結(jié)構(gòu)體癞己。該結(jié)構(gòu)體含有4個(gè)成員:name、num梭伐、age痹雅、score
注意大括號(hào)后面的分號(hào);不能少,這是一條完整的語(yǔ)句糊识。
2.定義結(jié)構(gòu)體類型的同時(shí)定義結(jié)構(gòu)體變量

struct stu
{
    char *name;  //姓名
    int num;  //學(xué)號(hào)
    int age;  //年齡
    float score;  //成績(jī)
}student;

在定義時(shí)直接聲明結(jié)構(gòu)體變量绩社,只需要將結(jié)構(gòu)體變量名放在花括號(hào)后面,并加上分號(hào)即可赂苗。
3.直接說(shuō)明結(jié)構(gòu)體變量

struct 
{
    char *name;  //姓名
    int num;  //學(xué)號(hào)
    int age;  //年齡
    float score;  //成績(jī)
} student;

這種定義方式并不常用愉耙,這樣做書寫雖然簡(jiǎn)單,但是因?yàn)闆](méi)有結(jié)構(gòu)體名拌滋,后面就沒(méi)法用該結(jié)構(gòu)體定義新的變量朴沿。
4.typedef重定義

typedef struct 
{
    char *name;  //姓名
    int num;  //學(xué)號(hào)
    int age;  //年齡
    float score;  //成績(jī)
} STU;
STU student;

這種方式比較常見,我們使用typedef重定義結(jié)構(gòu)體為STU败砂,這里STU就是此結(jié)構(gòu)體類型赌渣,可以用STU去定義結(jié)構(gòu)體變量

1.3 初始化

1.在定義結(jié)構(gòu)體變量的時(shí)候全部初始化

struct stu
{
    char *name;  //姓名
    int num;  //學(xué)號(hào)
    int age;  //年齡
    float score;  //成績(jī)
}student={“ha”,1234,56,99};

2.定義完結(jié)構(gòu)體變量后,之后只能單個(gè)賦值

struct stu
{
    char *name;  //姓名
    int num;  //學(xué)號(hào)
    int age;  //年齡
    float score;  //成績(jī)
};
struct stu  student;
student.name="ha";
student.num=1234;
student.age=56;
student.score=99;

1.4 調(diào)用

結(jié)構(gòu)體變量.成員

結(jié)構(gòu)體變量名+點(diǎn)('.')+成員就可以調(diào)用了

1.5 結(jié)構(gòu)體指針

當(dāng)一個(gè)指針變量指向結(jié)構(gòu)體時(shí)吠卷,我們就稱它為結(jié)構(gòu)體指針锡垄。C語(yǔ)言結(jié)構(gòu)體指針的定義形式一般為:

struct 結(jié)構(gòu)體名 *變量名;
//結(jié)構(gòu)體
struct stu{
    char *name;  //姓名
    int num;  //學(xué)號(hào)
    int age;  //年齡
    float score;  //成績(jī)
} stu1 = { "hah", 12, 18, 23, 136.5 };
//結(jié)構(gòu)體指針
struct stu *pstu = &stu1;

注意結(jié)構(gòu)體變量名和數(shù)組名不同,數(shù)組名在表達(dá)式中會(huì)被轉(zhuǎn)換為數(shù)組指針祭隔,而結(jié)構(gòu)體變量名不會(huì)货岭,無(wú)論在任何表達(dá)式中它表示的都是整個(gè)集合本身,要想取得結(jié)構(gòu)體變量的地址疾渴,必須在前面加&千贯,所以給 pstu 賦值只能寫作:

1.6 獲取結(jié)構(gòu)體成員

通過(guò)結(jié)構(gòu)體指針可以獲取結(jié)構(gòu)體成員,一般形式為:

(*pointer).memberName

或者:

pointer->memberName

第一種寫法中搞坝,.的優(yōu)先級(jí)高于搔谴,(pointer)兩邊的括號(hào)不能少。如果去掉括號(hào)寫作pointer.memberName桩撮,那么就等效于(pointer.memberName)敦第,這樣意義就完全不對(duì)了峰弹。

第二種寫法中,->是一個(gè)新的運(yùn)算符芜果,習(xí)慣稱它為“箭頭”鞠呈,有了它,可以通過(guò)結(jié)構(gòu)體指針直接取得結(jié)構(gòu)體成員右钾;這也是->在C語(yǔ)言中的唯一用途蚁吝。

1.7 結(jié)構(gòu)體內(nèi)存分析

注意點(diǎn)

  1. 給整個(gè)結(jié)構(gòu)體變量分配儲(chǔ)存空間和數(shù)組一樣,從內(nèi)存地址比較大的開始分配
  2. 給結(jié)構(gòu)體變量中的屬性分配儲(chǔ)存空間也和數(shù)組一樣,從所占內(nèi)存地址比較小的開始分配
  3. 定義結(jié)構(gòu)體類型不會(huì)分配儲(chǔ)存空間,只有定義結(jié)構(gòu)體變量的時(shí)候才會(huì)分配儲(chǔ)存空間
  • 結(jié)構(gòu)體在分配內(nèi)存的時(shí)候,會(huì)做一個(gè)內(nèi)存對(duì)齊的操作
  • 會(huì)先獲取所有屬性中占用內(nèi)存最大的屬性的字節(jié)數(shù)
  • 然后在開辟出最大屬性字節(jié)的內(nèi)存給第一個(gè)屬性,如果分配給第一個(gè)屬性之后還能繼續(xù)分配給第二個(gè)屬性,那么就繼續(xù)分配給第二個(gè)屬性
  • 如果分配給第一個(gè)屬性之后,剩余的內(nèi)存不夠分配給第二個(gè)屬性了,那么會(huì)再次開辟最大屬性的內(nèi)存,再次分配 依次類推
#include <stdio.h>

int main(){

    //定義結(jié)構(gòu)體
    struct Person
     {
        char name; // 1 個(gè)節(jié)點(diǎn)  //開辟4個(gè)字節(jié) char 占用1個(gè)
        int age;  // 4個(gè)字節(jié)   // 剩余三個(gè) 不夠int  再開辟4個(gè)字節(jié)
        int money; // 4個(gè)字節(jié) // 再開辟4個(gè)字節(jié)
    };

    struct Person p; // 所以p = 4+4+4

    printf("sizeof(p) = %i\n",sizeof(p)); // 12個(gè)字節(jié)
    return 0;
}

(二)共用體(聯(lián)合體):union

2.1概念

  • 所有變量共用一段空間
  • 每次分配按最大長(zhǎng)度進(jìn)行分配
  • 是一種構(gòu)造數(shù)據(jù)類型
  • 同一時(shí)刻只能保存一個(gè)成員的值
  • 不能直接引用共用體變量名

2.2定義

它的定義和結(jié)構(gòu)體一樣,分為先定義共用體再說(shuō)明共用體變量舀射、在定義共用體的同時(shí)說(shuō)明共用體變量窘茁、直接說(shuō)明共用體變量

union 共用體名{
    成員列表
};

示例:

//先定義共用體再說(shuō)明共用體變量
union data{
    int n;
    char ch;
    double f;
};
union data a, b, c;

2.3 引用

和結(jié)構(gòu)體一樣,通過(guò)共用體變量名 . 成員名

union data{
    int n;
    char ch;
    double f;
} a, b, c;
a.n=3;

關(guān)于共用體的詳細(xì)介紹可以看下這篇文章C語(yǔ)言共用體(C語(yǔ)言u(píng)nion用法)詳解脆烟,講到共用體這里要說(shuō)明一下大小端模式的問(wèn)題山林。

大小端

小端模式:低地址存放低字節(jié),高地址存放高字節(jié)
大端模式:低地址存放高字節(jié)浩淘,高地址存放低字節(jié)

(三)枚舉:enum

3.1 概念

  • 作用:列舉出所有的可能性捌朴,增強(qiáng)代碼的可閱讀性
  • 枚舉成員都是常量
  • 不能再對(duì)已經(jīng)定義好的枚舉常量賦值

3.1 定義

enum 枚舉名 
{
枚舉變量
};

示例:

enum week
{ 
Mon, Tues, Wed, Thurs, Fri, Sat, Sun
 };
typedef enum
{
Mon, Tues, Wed, Thurs, Fri, Sat, Sun
}Date;

枚舉是一種類型,通過(guò)它可以定義枚舉變量:

Date a,b,c

我們也可以給每個(gè)名字都指定一個(gè)值:

enum week{ Mon = 1, Tues = 2, Wed = 3, Thurs = 4, Fri = 5, Sat = 6, Sun = 7 };

更為簡(jiǎn)單的方法是只給第一個(gè)名字指定值:

enum week{ Mon = 1, Tues, Wed, Thurs, Fri, Sat, Sun };

這樣枚舉值就從 1 開始遞增张抄,跟上面的寫法是等效的砂蔽。
也可以在定義枚舉類型的同時(shí)定義變量:

enum week{ Mon = 1, Tues, Wed, Thurs, Fri, Sat, Sun } a, b, c;

有了枚舉變量,就可以把列表中的值賦給它:

enum week{ Mon = 1, Tues, Wed, Thurs, Fri, Sat, Sun };
enum week a = Mon, b = Wed, c = Sat;

或者:

enum week{ Mon = 1, Tues, Wed, Thurs, Fri, Sat, Sun } a = Mon, b = Wed, c = Sat;

特點(diǎn):可以在定義枚舉時(shí)給成員賦值署惯,被賦值的成員往后依次增加1左驾,也可以在中間改變某一個(gè)成員的值。

3.1 引用

直接使用就行极谊,需要注意的是**枚舉列表中的數(shù)據(jù)作用范圍是全局的诡右,不能在定義與它們名字相同的白能量;Mon轻猖、Tues帆吻、Wed 等都是常量,不能對(duì)它們賦值咙边,只能將它們的值賦給其他的變量猜煮。
示例:

#include <stdio.h>
int main(){
    enum week{ Mon = 1, Tues, Wed, Thurs, Fri, Sat, Sun } day;
    scanf("%d", &day);
    switch(day){
        case 1: puts("Monday"); break;
        case 2: puts("Tuesday"); break;
        case 3: puts("Wednesday"); break;
        case 4: puts("Thursday"); break;
        case 5: puts("Friday"); break;
        case 6: puts("Saturday"); break;
        case 7: puts("Sunday"); break;
        default: puts("Error!");
    }
    return 0;
}

Mon、Tues败许、Wed 這些名字都被替換成了對(duì)應(yīng)的數(shù)字王带。這意味著,Mon市殷、Tues愕撰、Wed 等都不是變量,它們不占用數(shù)據(jù)區(qū)(常量區(qū)、全局?jǐn)?shù)據(jù)區(qū)搞挣、棧區(qū)和堆區(qū))的內(nèi)存带迟,而是直接被編譯到命令里面,放到代碼區(qū)囱桨,所以不能用&取得它們的地址邮旷。這就是枚舉的本質(zhì)。


本文章僅供學(xué)習(xí)交流用禁止用作商業(yè)用途蝇摸,文中內(nèi)容來(lái)水枂編輯,如需轉(zhuǎn)載請(qǐng)告知办陷,謝謝合作

微信公眾號(hào):zhjj0729

微博:文藝to青年

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末貌夕,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子民镜,更是在濱河造成了極大的恐慌啡专,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,539評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件制圈,死亡現(xiàn)場(chǎng)離奇詭異们童,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)鲸鹦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門慧库,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人馋嗜,你說(shuō)我怎么就攤上這事齐板。” “怎么了葛菇?”我有些...
    開封第一講書人閱讀 165,871評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵甘磨,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我眯停,道長(zhǎng)济舆,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,963評(píng)論 1 295
  • 正文 為了忘掉前任莺债,我火速辦了婚禮滋觉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘九府。我一直安慰自己椎瘟,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評(píng)論 6 393
  • 文/花漫 我一把揭開白布侄旬。 她就那樣靜靜地躺著肺蔚,像睡著了一般。 火紅的嫁衣襯著肌膚如雪儡羔。 梳的紋絲不亂的頭發(fā)上宣羊,一...
    開封第一講書人閱讀 51,763評(píng)論 1 307
  • 那天璧诵,我揣著相機(jī)與錄音,去河邊找鬼仇冯。 笑死之宿,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的苛坚。 我是一名探鬼主播比被,決...
    沈念sama閱讀 40,468評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼泼舱!你這毒婦竟也來(lái)了等缀?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤娇昙,失蹤者是張志新(化名)和其女友劉穎尺迂,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體冒掌,經(jīng)...
    沈念sama閱讀 45,850評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡噪裕,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了股毫。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片膳音。...
    茶點(diǎn)故事閱讀 40,144評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖铃诬,靈堂內(nèi)的尸體忽然破棺而出严蓖,到底是詐尸還是另有隱情,我是刑警寧澤氧急,帶...
    沈念sama閱讀 35,823評(píng)論 5 346
  • 正文 年R本政府宣布颗胡,位于F島的核電站,受9級(jí)特大地震影響吩坝,放射性物質(zhì)發(fā)生泄漏毒姨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評(píng)論 3 331
  • 文/蒙蒙 一钉寝、第九天 我趴在偏房一處隱蔽的房頂上張望弧呐。 院中可真熱鬧,春花似錦嵌纲、人聲如沸俘枫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)鸠蚪。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間茅信,已是汗流浹背盾舌。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蘸鲸,地道東北人妖谴。 一個(gè)月前我還...
    沈念sama閱讀 48,415評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像酌摇,于是被迫代替她去往敵國(guó)和親膝舅。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評(píng)論 2 355

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