計算機與信息技術(shù)學(xué)院-大一上c語言programming tianmei_第1頁
計算機與信息技術(shù)學(xué)院-大一上c語言programming tianmei_第2頁
計算機與信息技術(shù)學(xué)院-大一上c語言programming tianmei_第3頁
計算機與信息技術(shù)學(xué)院-大一上c語言programming tianmei_第4頁
計算機與信息技術(shù)學(xué)院-大一上c語言programming tianmei_第5頁
已閱讀5頁,還剩27頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1第十五部分結(jié)構(gòu)體進階2結(jié)構(gòu)結(jié)構(gòu)是一種構(gòu)造數(shù)據(jù)類型用途:把不同類型的數(shù)據(jù)組合成一個整體-------自定義數(shù)據(jù)類型結(jié)構(gòu)類型定義struct[結(jié)構(gòu)類型名]{

類型標(biāo)識符成員名;類型標(biāo)識符成員名;

…………….};成員類型可以是基本型或構(gòu)造型struct是關(guān)鍵字,不能省略合法標(biāo)識符可省:無名結(jié)構(gòu)3例

struct

student{intnum;charname[20];charsex;intage;doublescore;charaddr[30];};namenumsexagescoreaddr4字節(jié)4字節(jié)20字節(jié)1字節(jié)8字節(jié)30字節(jié)……..結(jié)構(gòu)類型定義描述結(jié)構(gòu)的組織形式,不分配內(nèi)存例子圖解4先定義結(jié)構(gòu)類型,再定義結(jié)構(gòu)變量一般形式:struct結(jié)構(gòu)類型名{

類型標(biāo)識符成員名;類型標(biāo)識符成員名;

…………….};struct結(jié)構(gòu)類型名變量名表列;結(jié)構(gòu)變量的定義例structstudent{intnum;charname[20];charsex;intage;doublescore;charaddr[30];};structstudentstu1,stu2;5一般形式:struct結(jié)構(gòu)類型名{

類型標(biāo)識符成員名;類型標(biāo)識符成員名;

…………….}變量名表列;例structstudent{intnum;charname[20];charsex;intage;doublescore;charaddr[30];}stu1,stu2;定義結(jié)構(gòu)類型的同時定義結(jié)構(gòu)變量6一般形式:struct{

類型標(biāo)識符成員名;類型標(biāo)識符成員名;

…………….}變量名表列;例struct{intnum;charname[20];charsex;intage;doublescore;charaddr[30];}stu1,stu2;用無名結(jié)構(gòu)直接定義變量只能一次直接定義結(jié)構(gòu)變量

7結(jié)構(gòu)類型與結(jié)構(gòu)變量概念不同類型:不分配內(nèi)存;變量:分配內(nèi)存類型:不能賦值、存取、運算;變量:可以結(jié)構(gòu)可嵌套結(jié)構(gòu)成員名與程序中變量名可相同,不會混淆結(jié)構(gòu)類型及變量的作用域與生存期同其它類型變量說明:8形式一:struct結(jié)構(gòu)類型名{

類型標(biāo)識符成員名;類型標(biāo)識符成員名;

…………….};struct結(jié)構(gòu)類型名結(jié)構(gòu)變量={初始數(shù)據(jù)};例structstudent{intnum;charname[20];charsex;intage;charaddr[30];};structstudentstu1={112,“WangLin”,‘M’,19,“200BeijingRoad”};結(jié)構(gòu)變量的初始化9struct結(jié)構(gòu)類型名{

類型標(biāo)識符成員名;類型標(biāo)識符成員名;

…………….}結(jié)構(gòu)變量={初始數(shù)據(jù)};例structstudent{intnum;charname[20];charsex;intage;charaddr[30];}stu1={112,“WangLin”,‘M’,19,“200BeijingRoad”};

結(jié)構(gòu)變量的初始化形式二:10struct{

類型標(biāo)識符成員名;類型標(biāo)識符成員名;

…………….}結(jié)構(gòu)變量={初始數(shù)據(jù)};例struct{intnum;charname[20];charsex;intage;charaddr[30];}stu1={112,“WangLin”,‘M’,19,“200BeijingRoad”};

結(jié)構(gòu)變量的初始化形式三:11定義結(jié)構(gòu)類型程序里反復(fù)使用的結(jié)構(gòu)最好定義為類型

typedefstruct { doublex,y; }POINT; typedefstruct { POINTcenter; doubleradius; }CIRCLE; typedefstruct { POINTlu; POINTrd; }RECTANGLE;定義結(jié)構(gòu)成員時利用結(jié)構(gòu)標(biāo)志

structpoint { doublex,y; }; structcircle { structpointcenter; doubleradius; }; structrectangle { structpointlu; structpointrd; };12例定義為結(jié)構(gòu)類型,可以使程序更簡短清晰。例:居民身份證信息的結(jié)構(gòu)類型定義:

typedefstruct { charname[20];/*名字字符串用多長?*/ intsex; charnationality[10]; intborn_in[3]; charaddress[50]; intdate_of_issue[3]; intvalid_years; charissued_by[30]; charid_number[18]; charphoto[100][64]; }IDCARD;13無效結(jié)構(gòu)定義結(jié)構(gòu)成員不能是被描述的結(jié)構(gòu)本身。非法結(jié)構(gòu)描述的例子:

structinvalid { intn; structinvalidiv; };14結(jié)構(gòu)的實現(xiàn)結(jié)構(gòu)的實現(xiàn)一個結(jié)構(gòu)占一塊連續(xù)存儲,各成員順序存放。CIRCLE對象的存儲方式。

typedefstruct { POINTcenter;doubleradius; }CIRCLE;15對齊問題結(jié)構(gòu)成員類型可不同,可能出現(xiàn)對齊問題:

structexam { charaa; intnn; doublexx; };為了效率,硬件通常規(guī)定各種基本類型數(shù)據(jù)的擺放方式。例如,通常要求兩字節(jié)表示的整數(shù)從偶數(shù)地址的單元開始存放;需要8個字節(jié)表示的雙精度數(shù),可能要求從8(或4)的倍數(shù)地址的單元開始存放系統(tǒng)對整個結(jié)構(gòu)對象的存放也可能有起始位置要求結(jié)構(gòu)體大小,是否等于各個成員大小的和?16結(jié)構(gòu)成員可能不連續(xù),存放位置之間可能出現(xiàn)空位(結(jié)構(gòu)中的空洞)結(jié)構(gòu)大小未必等于成員大小之和。應(yīng)該用sizeof計算結(jié)構(gòu)大小(例如動態(tài)存儲分配時)structexam的可能布局:17結(jié)構(gòu)變量的使用設(shè)有POINTpt1,pt2;CIRCLEcirc1,circl2;整體賦值同類型結(jié)構(gòu)變量可整體賦值,效果是各成員分別賦值:pt2=pt1;結(jié)構(gòu)不能做相等/不等比較成員訪問訪問結(jié)構(gòu)成員用圓點運算符(.),具有最高優(yōu)先級,自左向右結(jié)合。例子:pt2.y=pt1.y+2.4;circ1.center.x=2.07;circ1.center.y=pt1.y;18將結(jié)構(gòu)circ2所表示的圓做平移,可以寫:circ2.center.x+=2.8;circ2.center.y+=0.24;結(jié)構(gòu)成員相當(dāng)于相應(yīng)類型的變量,操作由類型決定。/*簡單示例*/intmain(){POINTpt1={2.34,3.28},pt2;CIRCLEcirc1={{3.5,2.07},1.25};doublex,y;pt2.x=8.0;pt2.y=circ1.center.y+3.44;x=pt2.x-pt1.x;y=pt2.y-pt1.y;printf("distance:%f\n",sqrt(x*x+y*y));return0;}19

結(jié)構(gòu)、數(shù)組與指針結(jié)構(gòu)可以有數(shù)組成員,也可以定義一組以結(jié)構(gòu)為元素的數(shù)組(結(jié)構(gòu)數(shù)組)例:用結(jié)構(gòu)數(shù)組重構(gòu)C程序關(guān)鍵字統(tǒng)計程序。兩種實現(xiàn):1)兩維字符數(shù)組和計數(shù)器數(shù)組;2)用字符指針數(shù)組和計數(shù)器數(shù)組。更合理方式是用一個結(jié)構(gòu)表示與一個關(guān)鍵字有關(guān)的所有信息。為此可定義結(jié)構(gòu)類型。

typedefstruct { char*key; intcount; }KEYC;/*“關(guān)鍵字計數(shù)器”類型*/20程序數(shù)據(jù)結(jié)構(gòu)就是一個KEYC數(shù)組,定義時初始化:

KEYCkeytable[32]={ "auto",0,"break",0,...... "volatile",0,"while",0 };/*初始化中也可寫嵌套的括號*/程序的主循環(huán)可寫為:

inti;... while(getident(...,s)!=-1) for(i=0;i<32;i++) if(strcmp(s,keytable[i].key)==0){ keytable[i].count++; break; }21也可以用指針方式寫:

KEYC*p;... while(getident(...,s)>0) for(p=keytable;p<keytable+32;p++) if(strcmp(s,(*p).key)==0) { (*p).count++; break; }注意(*p).key寫法,這里必須寫括號。*p.key表示的是*(p.key),會出錯。經(jīng)常需要通過指向結(jié)構(gòu)的指針訪問被指結(jié)構(gòu)的成員。C語言為此專門提供運算符->:p->key等價于(*p).key22->具有最高優(yōu)先級(與圓點,函數(shù)調(diào)用()及數(shù)組元素訪問[]一樣),從左向右結(jié)合。 while(getident(s,...)>0) for(p=keytable;p<keytable+32;p++) if(strcmp(s,p->key)==0) { p->count++;break; }已經(jīng)討論了C語言的所有運算符,附錄A列出這些運算符:意義/優(yōu)先級/結(jié)合方式。請自己查閱。23結(jié)構(gòu)與函數(shù)結(jié)構(gòu)可作為函數(shù)參數(shù)和函數(shù)返回值。將結(jié)構(gòu)數(shù)據(jù)傳給函數(shù)有三種方式(返回值情況類似):傳結(jié)構(gòu)成員的值,只要該成員能賦值。傳遞整個結(jié)構(gòu)的值。結(jié)構(gòu)參數(shù)。傳結(jié)構(gòu)的地址(指針)。結(jié)構(gòu)指針參數(shù)。結(jié)構(gòu)參數(shù):實參結(jié)構(gòu)變量的值整個賦給形參,函數(shù)內(nèi)對形參的操作不會影響實參結(jié)構(gòu)指針參數(shù):傳結(jié)構(gòu)指針允許函數(shù)對實參結(jié)構(gòu)做任何操作,包括修改??梢员苊饨Y(jié)構(gòu)復(fù)制,若結(jié)構(gòu)很大,復(fù)制費時間,也可考慮用指針方式傳遞24處理結(jié)構(gòu)的函數(shù)例:由參數(shù)值構(gòu)造POINT類型的結(jié)構(gòu)值,函數(shù)定義:

POINTmkpoint1(doublex,doubley) { POINTtemp; temp.x=x; temp.y=y; returntemp; }返回值可賦給同類型變量。這種函數(shù)從成員值構(gòu)造結(jié)構(gòu)值,可稱為結(jié)構(gòu)值構(gòu)造函數(shù)。使用:pt1=mkpoint1(3.825,20.7);pt2=mkpoint1(pt1.x,0.0);temp隨函數(shù)結(jié)束而撤消,值返回,與局部變量的撤消無關(guān)。返回大的結(jié)構(gòu)值時需要復(fù)制大批數(shù)據(jù)25例由參數(shù)值構(gòu)造CIRCLE類型的結(jié)構(gòu)值,函數(shù)定義:

CIRCLEmkcircle(POINTc,doubler) { CIRCLEtemp; temp.center=c;temp.radius=r; returntemp; }函數(shù)有一個結(jié)構(gòu)參數(shù)。用例:circ1=mkcircle(pt1,5.254);circ2=mkcircle(circ1.center,11.7);circ3=mkcircle(mkpoint1(2.05,3.7),3.245);第三個例子:mkpoint返回POINT值,傳給mkcircle的POINT類型參數(shù)26值復(fù)制不一定合理定義計算兩個點之間距離的函數(shù),采用結(jié)構(gòu)參數(shù):

doubledistance(POINTp1,POINTp2) { doublex=p1.x-p2.x,y=p1.y-p2.y; returnsqrt(x*x+y*y); }復(fù)制整個結(jié)構(gòu),語義清楚。缺點是整體復(fù)制開銷較大例:打印身份證中身份證號和姓名的函數(shù):

voidprtIDCard0(IDCARDic){ printf("%s\n",ic.id_number); printf("%s\n\n",); }復(fù)制整個結(jié)構(gòu),大部分復(fù)制工作沒有價值27傳遞結(jié)構(gòu)指針可考慮傳遞結(jié)構(gòu)指針,下面函數(shù)完成同樣工作: voidprtIDCard(IDCARD*icp) { printf("%s\n%s\n\n",icp->id_number,icp->name); }只復(fù)制一個指針,更合理。設(shè)idc是IDCARD變量:prtIDCard(&idc);例,打印一個身份證結(jié)構(gòu)數(shù)組中的各身份證的信息: IDCARDidcs[10000],*p; ... /*假設(shè)idcs的元素都有了值*/ for(p=idcs;p<idcs;p++) prtIDCard(p);28動態(tài)生成結(jié)構(gòu),返回指針可采用動態(tài)存儲管理建立動態(tài)分配的結(jié)構(gòu)。下面函數(shù)建立POINT結(jié)構(gòu),返回地址:

POINT*mkpoint2(doublex,doubley) { POINT*p; p=(POINT*)malloc(sizeof(POINT)); p->x=x;p->y=y;returnp; }調(diào)用時用指向POINT的指針接收函數(shù)返回值。

POINT*q; q=mkpoint2(2.22,1.784);29實例使用實例:

POINT*pp1,*pp2; ...... pp1=mkpoint2(2.57,3.86); pp2=mkpoint2(pp1->y+2.6,pp1->x–0.7); ....../*使用建立的結(jié)構(gòu)*/ free(pp1);free(pp2);/*最后釋放存儲*/采用動態(tài)管理優(yōu)

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論