第七章 結(jié)構(gòu)體_第1頁
第七章 結(jié)構(gòu)體_第2頁
第七章 結(jié)構(gòu)體_第3頁
第七章 結(jié)構(gòu)體_第4頁
第七章 結(jié)構(gòu)體_第5頁
已閱讀5頁,還剩31頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

第八章結(jié)構(gòu)體8.1概述8.2定義結(jié)構(gòu)體變量的方法8.3結(jié)構(gòu)體變量的初始化8.4結(jié)構(gòu)體變量的引用8.5結(jié)構(gòu)體數(shù)組8.6指向結(jié)構(gòu)體數(shù)據(jù)的指針8.7用指針處理鏈表8.1概述

在實(shí)際問題中我們常需要把不同類型的幾個(gè)數(shù)據(jù)組合起來,構(gòu)成一個(gè)整體。如一個(gè)公司職員的個(gè)人信息,或?qū)W校中教師和學(xué)生的信息。以學(xué)生信息為例,它可能包括學(xué)生的學(xué)號(hào)、班級(jí)、姓名、性別、年齡、成績等。這時(shí)原有的那些數(shù)據(jù)類型就顯的有點(diǎn)無能為力了,所以引入一種新的數(shù)據(jù)類型----結(jié)構(gòu)體。結(jié)構(gòu)體是由一些邏輯相關(guān),但數(shù)據(jù)類型不同的分量組成的一組數(shù)據(jù)。注意:用戶需要先定義結(jié)構(gòu)體類型,之后才能定義結(jié)構(gòu)體變量注意不要忘了分號(hào)成員列表結(jié)構(gòu)體類型定義形式:struct

結(jié)構(gòu)體類型名{數(shù)據(jù)類型成員名1;

數(shù)據(jù)類型成員名2;::

數(shù)據(jù)類型成員名n;};關(guān)鍵字用戶定義的標(biāo)識(shí)符8.2定義結(jié)構(gòu)體變量的方法一、定義結(jié)構(gòu)體變量1.先定義結(jié)構(gòu)體類型,

再定義變量

structstudent{charname[10];

intage;floats1,s2;};

structstudentst1,st2;st1st2nameages1s2nameages1s2結(jié)構(gòu)體變量st1和st2各自都需要20個(gè)字節(jié)的存儲(chǔ)空間2.定義結(jié)構(gòu)體類型同時(shí)定義變量

structstudent{charname[10];

intage;floats1,s2;}

st1,st2;3.直接定義結(jié)構(gòu)體變量

struct

{charname[10];

intage;floats1,s2;}

st1,st2;4.說明:(1)結(jié)構(gòu)體變量具有結(jié)構(gòu)體類型的一切特征在內(nèi)存中結(jié)構(gòu)體變量占有一片連續(xù)的存儲(chǔ)單元存儲(chǔ)單元的字節(jié)數(shù)可用sizeof

運(yùn)算符算出

printf(“%d\n”,sizeof(structstudent));

printf(“%d\n”,sizeof(st1));(2)結(jié)構(gòu)體類型可以嵌套定義

例:structdate{intyear;

intmonth;

intday;};

structstud{charname[10];

structdatebirthday;floats1,s2;};

或:structstud{charname[10];

structdate{intyear;

intmonth;

intday;}

birthday;floats1,s2;};8.3結(jié)構(gòu)體變量的初始化structstudent{charname[10];

intage;floatscore1,score2;}st1={“Mary”,21,78,86};structstud{charname[10];

structdatebirthday;floatscore1,score2;};structstudst2={“John”,1980,11,23,89,95};structstudent{charname[10];

intage;floatscore1,score2;};structstudentst3;st3={“Mary”,21,78,86};正確初始化錯(cuò)誤,C不允許這樣賦值正確初始化8.4結(jié)構(gòu)體變量的引用1.引用結(jié)構(gòu)體變量中的成員

格式:

結(jié)構(gòu)體變量名.成員名structstudent{charname[10];

intage;floats1,s2;};注意:一般是對(duì)結(jié)構(gòu)體變量的各個(gè)成員分別進(jìn)行賦值st1={“Mary”,21,78,86};這樣的賦值是不允許的structstudentst1;strcpy(,“Mary”);st1.age=21;st1.s1=78;st1.s2=86;structdate{int

year;

intmonth;

intday;};structstud{charname[10];

int

age;

structdatebirthday;floats1,s2;};structstudst2;intage,year;strcpy(,“John”);st2.age=20;

st2.birthday.year=1980;st2.birthday.month=11;st2.birthday.day=23;st2.s1=89;st2.s2=95;age=24;year=2000;可以定義與結(jié)構(gòu)體變量成員名相同名字的變量它們之間不會(huì)發(fā)生混亂2.相同類型的結(jié)構(gòu)體變量可以進(jìn)行整體賦值

structdate{intyear;

intmonth;

intday;};structstud{charname[10];

intage;

structdatebirthday;floats1,s2;};structstudst1,st2,st3;strcpy(,“John”);st1.age=20;st1.birthday.year=1980;st1.birthday.month=11;st1.birthday.day=23;st1.s1=89;st1.s2=95;st2=st1;strcpy(,“Mary”);st3.age=20;st3.birthday=st1.birthday;st3.s1=76;st3.s2=85;注意要正確賦值的條件是變量st1已經(jīng)有了初值3.結(jié)構(gòu)體變量的輸入輸出

C語言不允許結(jié)構(gòu)體變量整體進(jìn)行輸入和輸出,

只能對(duì)結(jié)構(gòu)體變量的成員進(jìn)行輸入和輸出gets(

);scanf(“%d%d%d”,&st1.birthday.year,

&st1.birthday.month,&st1.birthday.day

);scanf(“%d%f%f”,&st1.age,&st1.s1,&st1.s2

);

puts();printf(“%4d”,st1.age);printf(“%d.%d.%d”,st1.birthday.year,st1.birthday.month,st1.birthday.day);printf(“%5.2f%5.2f\n”,st1.s1,st1.s2);8.5結(jié)構(gòu)體數(shù)組

一、結(jié)構(gòu)體數(shù)組的定義

1.先定義結(jié)構(gòu)體類型再定義結(jié)構(gòu)體數(shù)組

structstudent

{charname[10];

intage;floats1,s2;};

structstudentst[6];2.定義結(jié)構(gòu)體類型的同時(shí)定義數(shù)組

structstudent{charname[10];

intage;floats1,s2;}st[6];

3.直接定義結(jié)構(gòu)體數(shù)組

struct

{charname[10];

intage;floats1,s2;}st[6];

二、結(jié)構(gòu)體數(shù)組的初始化

將每個(gè)數(shù)組元素的數(shù)據(jù)用花括號(hào){}括起來structstudent{charname[10];

intage;floats1,s2;};structstudentst[3]={{“Mary”,21,78,86},

{“Alex”,20,90,80},{“Mike”,19,75,68}};Mary217886Alex209080Mike197568st[0]st[1]st[2]2.數(shù)組元素之間可以整體賦值也可以將一個(gè)元素賦給一個(gè)相同類型的結(jié)構(gòu)體變量

structstudentx,st[3]={{“Mary”,21,78,86},{“Alex”,…}};

st[2]=st[0];x=st[1];3.只能對(duì)數(shù)組元素的成員進(jìn)行輸入和輸出gets(st[2].name);scanf(“%d”,&st[2].age

);scanf(“%f%f”,&st[2].s1,&st[2].s2);puts(st[0].name);printf(“%4d%5.2f%5.2f\n”,st[0].age,st[0].s1,st[0].s2);都是結(jié)構(gòu)體變量的整體賦值三、結(jié)構(gòu)體數(shù)組的引用1.引用某個(gè)數(shù)組元素的成員例:

puts(st[0].name);

printf(“%d,%d”,st[1].age,st[1].s1);例:有30名學(xué)生,輸入每個(gè)學(xué)生信息包括學(xué)號(hào)、姓名、成績,要求找出成績最高者,并輸出他的信息#include<stdio.h>#defineN30voidmain(){structstudent{intn;charname[10];

intscore;};

structstudent

st[N];

inti,m;

intmax;for(i=0;i<N;i++)

scanf(“%d%s%d”,&st[i].n,st[i].name,&st[i].score);

max=st[0].score;for(i=1;i<N;i++)if(st[i].score>max){max=st[i].score;m=i;}printf(“%4d”,st[m].n);printf(“%10s”,st[m].name);printf(“%5d”,st[m].score);}例:按成績對(duì)學(xué)生信息進(jìn)行從高到底的排序#include<stdio.h>#defineN30voidmain(){

structstud{intn;charname[10];

ints;};

structstud

a[N],temp;

inti,j,k;for(i=0;i<N;i++)

scanf(“%d%s%d”,&a[i].n,a[i].name,&a[i].s);for(i=0;i<N-1;i++){for(j=i+1;j<N;j++)if(a[i].s<a[j].s)k=j;temp=a[k];

a[k]=a[i];

a[i]=temp;}for(i=0;i<N;i++)printf(“%4d%10s%4d”,

a[i].n,a[i].name,a[i].s);}8.6指向結(jié)構(gòu)體數(shù)據(jù)的指針

一、指向結(jié)構(gòu)體變量的指針

1.定義

structstudent{charname[20];

intage;floats1,s2;};

structstudentstu,*p;

p=&stu;2.成員的引用格式(1)

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

gets();(*p).age=21;p->s1=87;p->s2=90;(2)(*指針變量名).成員名

(*p).age(3)指針變量名->成員名

p->s1p只能指向一個(gè)結(jié)構(gòu)體變量,如:p=&stu;而不能指向結(jié)構(gòu)體變量的一個(gè)成員。如:p=&stu.age;是非法的。

->運(yùn)算符的優(yōu)先級(jí)最高。例如:struct

{charname[20];

intage;}*p;則表達(dá)式:

++p->age:表示age的值增加1。等價(jià)于++(p->age)

使用結(jié)構(gòu)體指針變量應(yīng)注意以下幾點(diǎn):

p不是結(jié)構(gòu)體變量(是指向結(jié)構(gòu)體變量的指針),因此不能寫成成員引用方式p.age的形式。二、指向結(jié)構(gòu)體數(shù)組的指針1.定義structstudentst[3],*p;2.使用for(p=st;p<st+3;p++){gets(p->name);

scanf(“%d%d

%d”,&p->age,&p->s1,&p->s2);}對(duì)于指向結(jié)構(gòu)體數(shù)組的指針:p只能指向一個(gè)結(jié)構(gòu)體數(shù)組的一個(gè)元素(相當(dāng)于變量),然后用->指向運(yùn)算符取其成員的值,而不能直接指向一個(gè)數(shù)組元素的成員。(++p)->age:表示p指針指向下一個(gè)數(shù)組元素后,再訪問其成員age。(p++)->age:先訪問age操作,再對(duì)指針p加1,使其指向下一個(gè)數(shù)組元素。結(jié)構(gòu)體變量作為函數(shù)參數(shù)1.函數(shù)的實(shí)參和形參都用結(jié)構(gòu)體變量,參數(shù)之間為值傳遞即:實(shí)參結(jié)構(gòu)體變量各成員的值依次傳給形參結(jié)構(gòu)體變量2.返回結(jié)構(gòu)體類型值的函數(shù)函數(shù)定義格式:結(jié)構(gòu)體類型名函數(shù)名(形參表列){函數(shù)體;}

例:structstudentfunct(intx,floaty){函數(shù)體;}注意結(jié)構(gòu)體類型是已經(jīng)定義好的三、結(jié)構(gòu)體與函數(shù)注意結(jié)構(gòu)變量作為參數(shù)傳遞時(shí),其實(shí)參與形參的結(jié)構(gòu)類型必須一致,傳遞時(shí)其實(shí)參只需指定其結(jié)構(gòu)變量名即可。當(dāng)實(shí)參為數(shù)組時(shí),其形參可以定義為同類型結(jié)構(gòu)的結(jié)構(gòu)數(shù)組或結(jié)構(gòu)指針。與普通變量一樣,結(jié)構(gòu)變量在函數(shù)內(nèi)部定義時(shí)為局部的,其值只在本函數(shù)范圍內(nèi)有效,不會(huì)影響其它函數(shù)將結(jié)構(gòu)傳遞給函數(shù)的方式有三種傳遞單個(gè)成員傳遞整個(gè)結(jié)構(gòu)傳遞指向結(jié)構(gòu)的指針傳遞結(jié)構(gòu)變量的地址可以實(shí)現(xiàn)結(jié)構(gòu)的傳址調(diào)用。結(jié)構(gòu)數(shù)組也可作為函數(shù)參數(shù)傳遞。在調(diào)用print時(shí),&stud做實(shí)參,將stud的地址傳遞給函數(shù)的形參p,這時(shí)p指向了結(jié)構(gòu)變量

stud的成員值。#include<string.h>#defineFORMAT“%d\n%s\n%6.2f\n”

structstudent{intnum;charname[20];floatscore;};main(){voidprint();

structstudentstud;stud.num=1001;

strcpy(,”michell”);stud.score=90.9;

print(&stud);}voidprint(structstudent*p){

printf(FORMAT,p->num,p->name,p->score);

printf(“\n”);}例:求學(xué)生成績的總分和平均分

#include<stdio.h>#defineN5structstud{charname[10];

ints[3];floatsum,ave;};structstudcomp(structstudx){intj;x.sum=0;for(j=0;j<3;j++)

x.sum=x.sum+x.s[j];

x.ave=x.sum/3;

return(x);}voidmain(){structstuda[N];

intj;for(j=0;j<N;j++){scanf(“%s%d%d%d”,a[j].name,&a[j].s[0],&a[j].s[1],&a[j].s[2]);}for(j=0;j<N;j++)a[j]=comp(a[j]);

for(j=0;j<N;j++){printf(“%10s%4d”,a[j].name,a[j].s[0]);printf(“%4d%4d”,a[j].s[1],a[j].s[2]);printf(“%8.2f%6.2f\n”,a[j].sum,a[j].ave);}}例:按成績對(duì)學(xué)生信息進(jìn)行從高到底的排序#include<stdio.h>#defineN30structstud{intn;charname[10];

ints;};voidinput(structstuda[]){inti;for(i=0;i<N;i++)

scanf(“%d%s%d”,&a[i].n,

a[i].name,&a[i].s);}

voidoutput(structstuda[]){inti;for(i=0;i<N;i++)printf(“%4d%10s%4d”,a[i].n,a[i].name,a[i].s);}

voidsort(structstuda[]){inti,j,k;

structstudtemp;for(i=0;i<N-1;i++){k=i;for(j=i+1;j<N;j++)if(a[i].s<a[j].s)k=j;

if(k!=i){temp=a[k];

a[k]=a[i];

a[i]=temp;}}}voidmain(){structstud

st[N];

input(st);

sort(st);

output(st);}8.7利用結(jié)構(gòu)體組織鏈表一、基本概念1.動(dòng)態(tài)存儲(chǔ)分配:根據(jù)需要臨時(shí)分配內(nèi)存單元用以存放數(shù)據(jù),

當(dāng)數(shù)據(jù)不用時(shí)可以隨時(shí)釋放內(nèi)存單元2.鏈表:是可以動(dòng)態(tài)地進(jìn)行存儲(chǔ)分配的一種數(shù)據(jù)結(jié)構(gòu)它是由一組動(dòng)態(tài)數(shù)據(jù)鏈接而成的序列3.結(jié)點(diǎn):鏈表中的每一個(gè)動(dòng)態(tài)數(shù)據(jù)稱為一個(gè)結(jié)點(diǎn)4.結(jié)點(diǎn)類型:是一個(gè)包含指針項(xiàng)的結(jié)構(gòu)體類型

一般由兩部分組成:(1)數(shù)據(jù)成員:存放數(shù)據(jù)(2)指針成員:存放下一個(gè)結(jié)點(diǎn)的地址struct

sd{intnum;

intscore;

struct

sd*next;};數(shù)據(jù)成員指針成員頭指針表頭結(jié)點(diǎn)表尾結(jié)點(diǎn)2010head2010142815709514281861570282NULL3NULL為空地址,表示鏈表到此結(jié)束二、簡單鏈表#include<stdio.h>struct

sd{intnum;

intscore;

struct

sd*next;};voidmain(){struct

sda,b,c,*head,*p;

head=&a;a.num=1;a.score=95;a.next=&b;b.num=2;b.score=86;b.next=&c;c.num=3;c.score=82;c.next=NULL;

p=head;while(p!=NULL){printf(“%3d%4d\n”,p->num,p->score);

p=p->next;}}head2010142815702010abc19514282861570382NULLp201014281570NULL說明:該程序雖然建立了一個(gè)鏈表,但這個(gè)鏈表是靜態(tài)的,因?yàn)樗慕Y(jié)點(diǎn)個(gè)數(shù)是固定的,不能按需要增加新的結(jié)點(diǎn),也不能按需要?jiǎng)h除結(jié)點(diǎn).這樣的鏈表并不實(shí)用,我們需要的是“動(dòng)態(tài)鏈表”三、處理動(dòng)態(tài)鏈表所需的函數(shù)(需用頭文件<stdlib.h>)1.malloc

函數(shù)原型:void*malloc(unsignedintsize)

作用:在內(nèi)存中開辟一個(gè)長度為size的連續(xù)存儲(chǔ)空間,

并將此存儲(chǔ)空間的起始地址帶回注意:(1)函數(shù)返回值是指針,但該指針是指向void類型的,因此在使用時(shí)希望這個(gè)指針指向其他類型需要用強(qiáng)制類型轉(zhuǎn)換(2)如果內(nèi)存缺少足夠大的空間進(jìn)行分配,則malloc

函數(shù)返回值為“空指針”(即NULL)例:struct

sd*p;p=(struct

sd*)

malloc(sizeof(struct

sd));強(qiáng)制類型轉(zhuǎn)換結(jié)構(gòu)體類型占用的字節(jié)長度2.free函數(shù)原型:voidfree(void*ptr)

作用:將指針變量ptr指向的存儲(chǔ)空間釋放注意:(1)ptr的值不是任意的地址,必須是程序中執(zhí)行malloc或

calloc函數(shù)所返回的地址(2)模型中ptr是void型,但調(diào)用free函數(shù)時(shí),參數(shù)可能是其他類型,計(jì)算機(jī)系統(tǒng)會(huì)自動(dòng)進(jìn)行轉(zhuǎn)換例:struct

sd*p;p=(struct

sd*)malloc(sizeof(struct

sd));

free(p);p42004200

四、鏈表應(yīng)用舉例

1.建立鏈表(表尾添加法)

#include<stdio.h>#include<stdlib.h>#defineSTstructstudentST{intnum;

intscore;ST*next;};#defineLENsizeof(ST)

intn;宏定義ST,以后書寫簡單求出結(jié)構(gòu)體類型占用的字節(jié)數(shù)全局量,n表示結(jié)點(diǎn)的個(gè)數(shù)ST*creat(void){ST*head,*p1,*p2;n=0;head=NULL;p1=(ST*)malloc(LEN);

scanf(“%d%d”,&p1->num,&p1->score);while(p1->num!=0){n=n+1;if(n==1)head=p1;elsep2->next=p1;p2=p1;p1=(ST*)malloc(LEN);

scanf(“%d%d”,&p1->num,&p1->score);}

p2->next=NULL;return(head);}head201014281570NULLp1p232642010201010951428n012320101428208630820014281570NULL1570157032642.輸出鏈表voidlist(ST*head){ST*p;p=head;while(p!=NULL){printf(“%3d%4d\n”,p->num,p->score);

p=p->next;

}}head201014281570201010951428208615703082NULLp201014281570NULLp120101428num20p22010head20101428157020101095142828615703082NULL1570n323.鏈表的刪除ST*del(ST*head,intnum){ST*p1,*p2;p1=head;while((num!=p1->num)&&(p1->next!=NULL)){p2=p1;p1=p1->next;}if(num==p1->num){if(p1==head)head=p1->next;elsep2->next=p1->next;

free(p1);n=n-1;

printf(“deleted!\n”);}else

溫馨提示

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

評(píng)論

0/150

提交評(píng)論