麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁(yè) > 系統(tǒng) > iOS > 正文

IOS開發(fā)之路--C語(yǔ)言構(gòu)造類型

2020-07-26 03:36:29
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

概述

在第一節(jié)中我們就提到C語(yǔ)言的構(gòu)造類型,分為:數(shù)組、結(jié)構(gòu)體、枚舉、共用體,當(dāng)然前面數(shù)組的內(nèi)容已經(jīng)說(shuō)了很多了,這一節(jié)將會(huì)重點(diǎn)說(shuō)一下其他三種類型。

結(jié)構(gòu)體 枚舉 共用體

結(jié)構(gòu)體

數(shù)組中存儲(chǔ)的是一系列相同的數(shù)據(jù)類型,那么如果想讓一個(gè)變量存儲(chǔ)不同的數(shù)據(jù)類型就要使用結(jié)構(gòu)體,結(jié)構(gòu)體定義類似于C++、C#、Java等高級(jí)語(yǔ)言中類的定義,但事實(shí)上它們又有著很大的區(qū)別。結(jié)構(gòu)體是一種類型,并非一個(gè)變量,只是這種類型可以由其他C語(yǔ)言基本類型共同組成。

//// main.c// ConstructedType//// Created by Kenshin Cui on 14-7-18.// Copyright (c) 2014年 Kenshin Cui. All rights reserved.//#include <stdio.h>//結(jié)構(gòu)體類型Datestruct Date{ int year; int month; int day;};struct Person{ char *name; int age; struct Date birthday;//一個(gè)結(jié)構(gòu)體中使用了另一個(gè)結(jié)構(gòu)體類型,結(jié)構(gòu)體類型變量聲明前必須加上struct關(guān)鍵字 float height;};int main(int argc, const char * argv[]) { struct Person p={"Kenshin",28,{1986,8,8},1.72}; //定義結(jié)構(gòu)體變量并初始化,不允許先定義再初始化,例如:struct Person p;p={"Kenshin",28,{1986,8,8},1.72};是錯(cuò)誤的  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);  //結(jié)果:name=Kenshin,age=28,birthday=1986-8-8,height=1.72,結(jié)構(gòu)體的引用是通過(guò)"結(jié)構(gòu)體變量.成員名稱"  printf("len(Date)=%lu,len(Person)=%lu/n",sizeof(struct Date),sizeof(struct Person));  //結(jié)果:len(Date)=12,len(Person)=32  return 0;}

對(duì)于上面的例子需要做出如下說(shuō)明:

可以在定義結(jié)構(gòu)體類型的同時(shí)聲明結(jié)構(gòu)體變量;
如果定義結(jié)構(gòu)體類型的同時(shí)聲明結(jié)構(gòu)體變量,此時(shí)結(jié)構(gòu)體名稱可以省略;
定義結(jié)構(gòu)體類型并不會(huì)分配內(nèi)存,在定義結(jié)構(gòu)體變量的時(shí)候才進(jìn)行內(nèi)存分配(同基本類型時(shí)類似的);
結(jié)構(gòu)體類型的所占用內(nèi)存大型等于所有成員占用內(nèi)存大小之和(如果不考慮內(nèi)存對(duì)齊的前提下);

對(duì)第4點(diǎn)需要進(jìn)行說(shuō)明,例如上面代碼是在64位編譯器下運(yùn)行的結(jié)果(int長(zhǎng)度4,char長(zhǎng)度1,float類型4),Date=4+4+4=12。但是對(duì)于Person卻沒(méi)有那么簡(jiǎn)單了,因?yàn)榘凑照7绞接?jì)算Person=8+4+12+4=28,但是從上面代碼中給出的結(jié)果是32,為什么呢?這里不得不引入一個(gè)概念“內(nèi)存對(duì)齊”,關(guān)于內(nèi)存對(duì)齊的概念在這里不做詳細(xì)說(shuō)明,大家需要了解的是:在Mac OS X中對(duì)齊參數(shù)默認(rèn)為8(可以通過(guò)在代碼中添加#pragma pack(8)改變對(duì)齊參數(shù)),如果結(jié)構(gòu)體中的類型不大于8,那么結(jié)構(gòu)體長(zhǎng)度就是其成員類型之和,但是如果成員變量的長(zhǎng)度大于這個(gè)對(duì)齊參數(shù)那么得到的結(jié)果就不一定是各個(gè)成員變量之和了。Person類型的長(zhǎng)度之所以是32,其實(shí)主要原因是因?yàn)镈ate類型長(zhǎng)度12在存儲(chǔ)時(shí)其偏移量12不是8的倍數(shù),考慮到內(nèi)存對(duì)齊的原因需要添加4個(gè)補(bǔ)齊長(zhǎng)度,這里使用表格的形式列出了具體原因:

表格具體來(lái)源請(qǐng)觀看下面的視頻(注意由于錄制軟件的原因前幾秒不清晰但是不影響分析):

接下來(lái)看一下結(jié)構(gòu)體數(shù)組、指向結(jié)構(gòu)體的指針:

//// 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); } /*輸出結(jié)果:  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); /*輸出結(jié)果:  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); /*輸出結(jié)果:  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); /*輸出結(jié)果:  name=Kenshin,age=28,birthday=1986-8-8,height=1.72  */  return 0;}

結(jié)構(gòu)體作為函數(shù)參數(shù)傳遞的是成員的值(值傳遞而不是引用傳遞),對(duì)于結(jié)構(gòu)體指針而言可以通過(guò)”->”操作符進(jìn)行訪問(wèn)。

枚舉

枚舉類型是比較簡(jiǎn)單的一種數(shù)據(jù)類型,事實(shí)上在C語(yǔ)言中枚舉類型是作為整形常量進(jìn)行處理的,通常稱為“枚舉常量”。

//// main.c// ConstructedType//// Created by Kenshin Cui on 14-7-18.// Copyright (c) 2014年 Kenshin Cui. All rights reserved.//#include <stdio.h>enum Season{ //默認(rèn)情況下spring=0,summer=1,autumn=2,winter=3 spring, summer, autumn, winter};int main(int argc, const char * argv[]) { enum Season season=summer; //枚舉賦值,等價(jià)于season=1 printf("summer=%d/n",season); //結(jié)果:summer=1  for(season=spring;season<=winter;++season){  printf("element value=%d/n",season); } /*結(jié)果:  element value=0  element value=1  element value=2  element value=3  */ return 0;}

需要注意的是枚舉成員默認(rèn)值從0開始,如果給其中一個(gè)成員賦值,其它后面的成員將依次賦值,例如上面如果summer手動(dòng)指定為8,則autumn=9,winter=10,而sprint還是0。

共用體

共用體又叫聯(lián)合,因?yàn)樗年P(guān)鍵字是union(貌似數(shù)據(jù)庫(kù)操作經(jīng)常使用這個(gè)關(guān)鍵字),它的使用不像枚舉和結(jié)構(gòu)體那么頻繁,但是作為C語(yǔ)言中的一種數(shù)據(jù)類型我們也有必要弄清它的用法。從前面的分析我們知道結(jié)構(gòu)體的總長(zhǎng)度等于所有成員的和(當(dāng)然此時(shí)還可能遇到對(duì)齊問(wèn)題),但是和結(jié)構(gòu)體不同的是共用體所有成員共用一塊內(nèi)存,順序從低地址開始存放,一次只能使用其中一個(gè)成員,union最終大小由共用體中最大的成員決定,對(duì)某一成員賦值可能會(huì)覆蓋另一個(gè)成員。

//// 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); //結(jié)果:address(Type)=5fbff7b8,address(t.a)=5fbff7b8,address(t.b)=5fbff7b8,address(t.c)=5fbff7b8  printf("len(Type)=%d/n",sizeof(union Type)); //結(jié)果:len(Type)=4  printf("t.a=%d,t.b=%d,t.c=%d/n",t.a,t.b,t.c); //結(jié)果:t.a=4,t.b=260,t.c=65796  return 0;}

這里需要重點(diǎn)解釋一個(gè)問(wèn)題:為什么t.a、t.b、t.c輸出結(jié)果分別是4、260、65796,當(dāng)然t.c等于65796并不奇怪,但是t.a前面賦值為'a'不應(yīng)該是97嗎,而t.b不應(yīng)該是10嗎?其實(shí)如果弄清這個(gè)問(wèn)題共用體的概念基本就清楚了。

根據(jù)前面提到的,共用體其實(shí)每次只能使用其中一個(gè)成員,對(duì)于上面的代碼經(jīng)過(guò)三次賦值最終使用的其實(shí)就是t.c,而通過(guò)上面的輸出結(jié)果我們也確實(shí)看到c是有效的。共用體有一個(gè)特點(diǎn)就是它的成員存儲(chǔ)在同一塊內(nèi)存區(qū)域,這塊區(qū)域的大小需要根據(jù)它的成員中長(zhǎng)度最大的成員長(zhǎng)度而定。由于上面的代碼是在64位編譯器下編譯的,具體長(zhǎng)度:char=1,short int=2,int=4,所以得出結(jié)論,Type的長(zhǎng)度為4,又根據(jù)上面輸出的地址,可以得到下面的存儲(chǔ)信息(注意數(shù)據(jù)的存儲(chǔ)方式:高地址存儲(chǔ)高位,低地址存儲(chǔ)地位):

當(dāng)讀取c的時(shí)候,它的二進(jìn)制是“00000000 00000001 00000001 00000100”,換算成十進(jìn)制就是65796;而經(jīng)過(guò)三次賦值后,此時(shí)b的存儲(chǔ)就已經(jīng)被c成員的低位數(shù)據(jù)覆蓋,b的長(zhǎng)度是二,所以從起始地址取兩個(gè)字節(jié)得到的二進(jìn)制數(shù)據(jù)此時(shí)是“00000001 00000100”(b原來(lái)的數(shù)據(jù)已經(jīng)被c低2位數(shù)據(jù)覆蓋,其實(shí)此時(shí)就是c的低2位數(shù)據(jù)),換算成十進(jìn)制就是260;類似的a此時(shí)的數(shù)據(jù)就是c的低一位數(shù)據(jù)”00000100”,換算成十進(jìn)制就是4。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 91麻豆精品国产91久久久更新资源速度超快 | 日本羞羞影院 | 31freehdxxxx欧美 | 日韩中文字幕三区 | 亚洲性生活免费视频 | 日本韩国欧美一级片 | 久国久产久精永久网页 | 美女视频黄a视频免费全过程 | 国产成人av免费看 | 国产喷白浆10p| 精品亚洲视频在线 | 一区二区免费网站 | xx53xx| 国产毛片在线 | 欧美五月婷婷 | 可以看逼的视频 | 久草视频国产在线 | 成人午夜免费福利 | 午夜久久视频 | 成年性羞羞视频免费观看 | 亚洲精品成人久久 | 午夜精品一区二区三区免费 | 精品久久久久久久久久久αⅴ | 久久久久久99 | 49vvv| 国产女厕一区二区三区在线视 | 羞羞的网址 | 国产成人77亚洲精品www | 色淫影院 | 成人青青草 | 黄 色 免费网 站 成 人 | 在线成人影视 | 香蕉黄色网 | 亚洲第一成人在线观看 | 成人在线视频网 | 性猛aa久久久 | 国产九色在线观看 | 国产精品久久久久久模特 | 成人勉费视频 | 黄色av片三级三级三级免费看 | 国产精品热 |