《CC++語言程序設(shè)計(jì)案例教程》課件-第6章結(jié)構(gòu)體_第1頁
《CC++語言程序設(shè)計(jì)案例教程》課件-第6章結(jié)構(gòu)體_第2頁
《CC++語言程序設(shè)計(jì)案例教程》課件-第6章結(jié)構(gòu)體_第3頁
《CC++語言程序設(shè)計(jì)案例教程》課件-第6章結(jié)構(gòu)體_第4頁
《CC++語言程序設(shè)計(jì)案例教程》課件-第6章結(jié)構(gòu)體_第5頁
已閱讀5頁,還剩63頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1第6章結(jié)構(gòu)體和共用體C

語言程序設(shè)計(jì)案例教程2024/12/232第6章結(jié)構(gòu)體與共用體6.1結(jié)構(gòu)體類型和結(jié)構(gòu)體變量6.2結(jié)構(gòu)體變量的引用6.3結(jié)構(gòu)體數(shù)組6.4指向結(jié)構(gòu)體類型數(shù)據(jù)的指針6.5結(jié)構(gòu)體與函數(shù)6.6自學(xué)共用體枚舉類型要求掌握結(jié)構(gòu)體類型的變量和引用方法,以及結(jié)構(gòu)體數(shù)組。(6.1---6.3)重點(diǎn)掌握結(jié)構(gòu)體類型數(shù)據(jù)的指針(6.4)了解公用體、枚舉類型的定義及基本概念(6.6----6.8)學(xué)習(xí)內(nèi)容

學(xué)習(xí)目標(biāo)

2024/12/233一個(gè)學(xué)生的信息有學(xué)號(hào)、姓名、性別、年齡、住址、成績(jī)等。一本圖書的信息有分類編號(hào)、書名、作者、出版社、出版日期、價(jià)格、庫(kù)存量等。如何描述這些類型不同的相關(guān)數(shù)據(jù)?6.1結(jié)構(gòu)體結(jié)構(gòu)體的引入?結(jié)構(gòu)體——一種構(gòu)造類型數(shù)據(jù)

結(jié)構(gòu)體由若干不同類型的數(shù)據(jù)項(xiàng)組成,構(gòu)成結(jié)構(gòu)體的各個(gè)數(shù)據(jù)項(xiàng)稱為結(jié)構(gòu)體成員。在實(shí)際應(yīng)用中,有時(shí)需要將不同類型的數(shù)據(jù)組合成一個(gè)有機(jī)的整體。如果將這些項(xiàng)分別定義為獨(dú)立的基本類型變量,很難反映它們之間存在的內(nèi)在聯(lián)系。希望能將其有機(jī)結(jié)合為一個(gè)整體,使其易于使用和操作,既能極大提高這類數(shù)據(jù)的處理效率更能真實(shí)的反映客觀世界。2024/12/234案例一完成學(xué)生基本信息的保存并輸出1.問題描述完成學(xué)生基本信息的保存并輸出(姓名、性別、學(xué)號(hào)、成績(jī)、本學(xué)期綜合排名等級(jí))。2.問題分析使用結(jié)構(gòu)體類型變量保存學(xué)生基本信息,注意結(jié)構(gòu)體和嵌套結(jié)構(gòu)體定義、賦值、輸出的方式。2024/12/2353.?C語言代碼#include<stdio.h>structcredit /*定義結(jié)構(gòu)體類型credit*/{floatscore; /*score為結(jié)構(gòu)體credit成員,表示學(xué)生成績(jī)*/chargrade;};structstudent /*定義結(jié)構(gòu)體類型student*/{char*sname; /*sname為結(jié)構(gòu)體student成員(指針類型)*/charssex;intsnum;structcredituser; /*user是結(jié)構(gòu)體類型credit的變量,在結(jié)構(gòu)體類型student定義中嵌入另一 個(gè)結(jié)構(gòu)體類型credit變量為結(jié)構(gòu)體類型student成員*/}stu1={"zhangxiao",'M',18091009,89.8,'B'},stu2;/*stu1、stu2是結(jié)構(gòu)體類型student的變量*/main(){structcredituser; /*user是另一結(jié)構(gòu)體類型credit的變量*/

stu2.sname="sunjierui";stu2.ssex='M';stu2.snum=18091019;printf("請(qǐng)輸入stu2的學(xué)期排名等級(jí)和成績(jī)\n");scanf("%c%f",&stu2.user.grade,&stu2.user.score);printf("stu2.sname=%s,stu2.ssex=%c,stu2.snum=%d\n",stu2.sname,stu2.ssex,stu2.snum);printf("stu2.user.score=%f,stu2.user.grade=%c\n",stu2.user.score,stu2.user.grade);}2024/12/2364.程序運(yùn)行結(jié)果請(qǐng)輸入stu2的學(xué)期排名等級(jí)和成績(jī)C78stu2.sname=sunjierui,stu2.ssex=M,stu2.snum=18091019stu2.user.score=78.000000,stu2.user.grade=C2024/12/2376.1結(jié)構(gòu)體類型與結(jié)構(gòu)體變量結(jié)構(gòu)體是C語言的構(gòu)造類型。如案例一中,structcredit和structstudent都是結(jié)構(gòu)體類型。結(jié)構(gòu)體成員是有邏輯聯(lián)系的變量。案例一中成員變量charssex、intsnum、structcredituser的取值都與成員變量char*sname有關(guān),于是把這些成員封裝在一起形成一個(gè)獨(dú)立的類型——結(jié)構(gòu)體類型。結(jié)構(gòu)體成員在內(nèi)存中占據(jù)連續(xù)的存儲(chǔ)單元。把具有內(nèi)在聯(lián)系的數(shù)據(jù)有機(jī)的結(jié)合為一個(gè)整體有易于使用和操作,可提高這類數(shù)據(jù)的處理效率,更真實(shí)的反映客觀世界。2024/12/2386.1.1結(jié)構(gòu)體類型與結(jié)構(gòu)體變量的定義

“結(jié)構(gòu)體”是自定義的構(gòu)造類型,可根據(jù)需要構(gòu)造結(jié)構(gòu)體中成員。由于不是系統(tǒng)定義的標(biāo)準(zhǔn)類型,結(jié)構(gòu)體類型要先定義,再定義結(jié)構(gòu)體變量。1.結(jié)構(gòu)體類型定義結(jié)構(gòu)體類型的一般形式為:struct結(jié)構(gòu)體名{

數(shù)據(jù)類型成員變量1;數(shù)據(jù)類型成員變量2;

...

數(shù)據(jù)類型成員變量n;};結(jié)構(gòu)體中的成員變量可以是基本數(shù)據(jù)類型,也可以是指針類型,或結(jié)構(gòu)體類型等。2024/12/2392.結(jié)構(gòu)體變量的定義結(jié)構(gòu)體類型變量的定義與其他類型的變量的定義方法是一樣的。因?yàn)榻Y(jié)構(gòu)體類型是根據(jù)具體問題先自行定義的,這樣便給結(jié)構(gòu)體類型變量的定義形式增加了靈活性。結(jié)構(gòu)體變量定義共有三種形式:(1)先定義結(jié)構(gòu)體類型,再定義結(jié)構(gòu)體類型變量。定義格式如下:struct結(jié)構(gòu)體名{

成員變量項(xiàng)表列};struct結(jié)構(gòu)體類型名結(jié)構(gòu)體變量名;例如:

structstudent /*定義結(jié)構(gòu)體類型student*/{char*sname; /*結(jié)構(gòu)體student類型的成員*/charssex;intsnum;structcredituser; /*user是另一結(jié)構(gòu)體類型credit的變量,對(duì)成員的使用是在結(jié)構(gòu)體變量的基礎(chǔ)上*/};structstudentstu1,stu2;/*結(jié)構(gòu)體變量定義*/2024/12/2310(2)定義結(jié)構(gòu)體類型同時(shí)定義結(jié)構(gòu)體類型變量。定義格式如下:struct結(jié)構(gòu)體類型名{

成員變量項(xiàng)表列}結(jié)構(gòu)體變量名;例如:structstudent{char*sname;charssex;intsnum;structcredituser;}stu1,stu2; /*結(jié)構(gòu)體變量定義*/2024/12/2311說明:①這兩種結(jié)構(gòu)體類型變量定義方法可以很方便的在定義之后的任意位置說明該結(jié)構(gòu)體類型變量。②結(jié)構(gòu)體類型的聲明可以在函數(shù)內(nèi),也可以在函數(shù)外,分別屬于局部和全局結(jié)構(gòu)體類型。全局的結(jié)構(gòu)體類型可以定義局部和全局的結(jié)構(gòu)體變量,局部的結(jié)構(gòu)體類型只可以定義局部的結(jié)構(gòu)體變量。(3)直接定義結(jié)構(gòu)體類型變量。定義格式如下:struct{

成員項(xiàng)表列}結(jié)構(gòu)體變量名;例如:struct /*定義無名結(jié)構(gòu)體*/{char*sname;charssex;intsnum;structcredituser;}stu1,stu2;/*結(jié)構(gòu)體變量定義*/說明:該定義方法由于無法記錄該結(jié)構(gòu)體類型,所以不能在主函數(shù)中再定義新的結(jié)構(gòu)的變量(無結(jié)構(gòu)體名),而其他定義方式可以在main()函數(shù)中再定義新的結(jié)構(gòu)體類型變量。注意:編譯系統(tǒng)不為結(jié)構(gòu)體類型分配空間,只對(duì)結(jié)構(gòu)體變量分配空間,結(jié)構(gòu)體變量的存儲(chǔ)空間大小是每個(gè)成員變量存儲(chǔ)空間之和。2024/12/23126.1.2結(jié)構(gòu)體變量的使用

如果要對(duì)結(jié)構(gòu)體成員進(jìn)行操作,首先要通過對(duì)結(jié)構(gòu)體變量的使用。1.結(jié)構(gòu)體變量的引用對(duì)結(jié)構(gòu)體變量的操作,實(shí)質(zhì)是對(duì)成員的操作,結(jié)構(gòu)體變量對(duì)成員引用的一般形式為結(jié)構(gòu)體變量.成員名例如,在案例一中通過、stu2.snum引用形式完成對(duì)、stu2.snum操作,如賦值、計(jì)算和輸出。如果有一個(gè)結(jié)構(gòu)成員屬于另一個(gè)結(jié)構(gòu)體類型時(shí),例如在structstudent結(jié)構(gòu)體類型中成員user是另一結(jié)構(gòu)體類型structcredit的變量,這時(shí)引用方式是stu2.user.grade,由外向里一級(jí)一級(jí)找到最低一級(jí)。2024/12/23132.結(jié)構(gòu)體變量的賦值結(jié)構(gòu)變量與其他變量相同,可以在定義它的同時(shí)進(jìn)行初始化,用一對(duì)大括號(hào)包圍的初值表對(duì)該結(jié)構(gòu)變量的每個(gè)成員變量賦初值,初值表按成員項(xiàng)排列的先后順序一一對(duì)應(yīng)賦值。每個(gè)初值數(shù)據(jù)類型必須與其對(duì)應(yīng)的成員變量數(shù)據(jù)相符合。例如:structstudent /*定義全局結(jié)構(gòu)體類型student*/{char*sname; /**sname、ssex等都是結(jié)構(gòu)體student成員*/charssex;intsnum;structcredituser;/*user是另一結(jié)構(gòu)體類型credit的變量*/}stu1={"zhangxiao",'M',18091009,89.8,'B'};/*定義全局結(jié)構(gòu)體變量stu1,并初始化*/#include"stdio.h"main(){structstudentstu2={"sunli",'w',18991019,78,'C'};/*定義局部結(jié)構(gòu)體變量stu2,并初始化*/...}注意:①不能對(duì)結(jié)構(gòu)體整體賦值和整體輸出;scanf("%s%c%d%f%c",stu2);或printf("%s%c%d%f%c",stu2);②不同結(jié)構(gòu)體類型的結(jié)構(gòu)體變量不能互相賦值。stu2=stu3;這兩個(gè)結(jié)構(gòu)體變量的結(jié)構(gòu)體類型必須相同才可以整體賦值。2024/12/2314案例二結(jié)構(gòu)體數(shù)組的使用1.問題描述根據(jù)學(xué)號(hào)查找對(duì)應(yīng)學(xué)生的姓名和成績(jī)。2.問題分析建立結(jié)構(gòu)體數(shù)組,數(shù)組成員保存學(xué)生基本信息(姓名、性別、學(xué)號(hào)、成績(jī))。2024/12/23153.C語言代碼#include<stdio.h>structstudent{char*sname;charssex;intsnum;floatscore[2];}stu[]={{"ZhaoLei",'M',18091210,{89,76.8}},{"LiLie",'M',18091201,{76.3,89.4}},{"SunZhongJie",'W',18091226,{89.5,90.4}}};/*結(jié)構(gòu)體數(shù)組初始化,保存各學(xué)生信息*/main(){unsignedlongintstu_len=sizeof(stu)/sizeof(stu[0]);/*計(jì)算數(shù)組長(zhǎng)度*/inti,num,j;printf("請(qǐng)輸入學(xué)生學(xué)號(hào):");scanf("%d",&num);for(i=0;i<stu_len;i++)if(num==stu[i].snum)break;printf("thename=%s,ssex=%c\n",stu[i].sname,stu[i].ssex);for(j=0;j<2;j++)printf("成績(jī)%d是%.4f\n",j+1,stu[i].score[j]);printf("\n");}2024/12/23164.程序運(yùn)行結(jié)果請(qǐng)輸入學(xué)生學(xué)號(hào):18091210thename=ZhaoLie,ssex=M成績(jī)1是89.0000成績(jī)2是76.80002024/12/23176.2結(jié)構(gòu)體數(shù)組

在實(shí)際中,可能要處理多個(gè)結(jié)構(gòu)體變量,這時(shí)可以使用結(jié)構(gòu)體數(shù)組。結(jié)構(gòu)體數(shù)組結(jié)合了“結(jié)構(gòu)體”與“數(shù)組”的特點(diǎn),既可以體現(xiàn)結(jié)構(gòu)體成員的特點(diǎn),又可以對(duì)數(shù)組成員進(jìn)行批量處理。2024/12/23186.2.1結(jié)構(gòu)體數(shù)組定義

結(jié)構(gòu)體數(shù)組的定義與結(jié)構(gòu)體變量的定義基本相同,也有三種形式。例如:采用結(jié)構(gòu)體變量定義的第一種形式的定義格式如下:structstudent /*定義結(jié)構(gòu)體類型student*/{char*sname; /*結(jié)構(gòu)體類型student成員*/charssex;intsnum;structcredituser; /*user是另一結(jié)構(gòu)體類型credit的變量*/};structstudentstu[4];2024/12/23196.2.2結(jié)構(gòu)體數(shù)組的使用

結(jié)構(gòu)體數(shù)組的使用與之前的數(shù)組使用的方法基本相同。(1)結(jié)構(gòu)體數(shù)組的引用與初始化。結(jié)構(gòu)體數(shù)組引用格式為結(jié)構(gòu)體數(shù)組名[下標(biāo)].成員名例如:采用結(jié)構(gòu)體變量定義形式2定義結(jié)構(gòu)體數(shù)組,并完成初始化。structstudent /*定義結(jié)構(gòu)體類型student*/{char*sname; /*結(jié)構(gòu)體類型student成員*/charssex;intsnum;floatscore;}stu[4]; /*定義stu為含有4個(gè)元素的全局結(jié)構(gòu)體數(shù)組*/可以使用stu[0].ssex、stu[3].score引用方式。2024/12/2320(2)結(jié)構(gòu)體類型數(shù)組初始化與結(jié)構(gòu)體類型變量形式相同,只不過數(shù)組每個(gè)元素是結(jié)構(gòu)體類型成員。說明:(1)如案例二所示,結(jié)構(gòu)體數(shù)組初始化時(shí)所有數(shù)組元素要用最外層花括號(hào)括起來。為了表述清晰,一般會(huì)把每個(gè)數(shù)組元素也用花括號(hào)括起來。(2)系統(tǒng)開辟連續(xù)空間存放結(jié)構(gòu)體數(shù)組中的元素。結(jié)構(gòu)體數(shù)組名是結(jié)構(gòu)體數(shù)組的首地址。(3)可以在定義結(jié)構(gòu)體類型之后直接定義結(jié)構(gòu)體數(shù)組并初始化。(4)可以先定義結(jié)構(gòu)體數(shù)組,在程序運(yùn)行過程中完成賦值。2024/12/2321例6.1完成學(xué)生信息的錄入(姓名、性別、學(xué)號(hào))。#include<stdio.h>#include<string.h>structstudent{charsname[20];charssex;intsnum;}stu[3]; /*定義stu為含有3個(gè)元素的全局結(jié)構(gòu)體數(shù)組*/main(){inti,j;printf("inputthe3students'ssname,ssex,sunm\n");for(i=0;i<3;i++) /*通過循環(huán)完成對(duì)結(jié)構(gòu)體數(shù)組中元素賦值*/{printf("thesname:");fflush(stdin);gets(stu[i].sname);fflush(stdin); /*避免將輸入sname之后的回車鍵作為字符賦值給字符類型的ssex*/printf("thessexandsnum:");

scanf("%c%d",&stu[i].ssex,&stu[i].snum);printf("\n");}}2024/12/2322程序運(yùn)行結(jié)果如下:inputthe3stuents'ssname,ssex,sunmthesname:ZhangJiathessexandsnum:M18010112thesname:SunJieChaothessexandsnum:W18010223thesname:ZhaoHanthessexandsnum:W180103212024/12/2323案例三指向結(jié)構(gòu)體類型數(shù)組指針的使用1.問題描述查找學(xué)生成績(jī)最低的學(xué)生信息。2.問題分析使用結(jié)構(gòu)體數(shù)組保存學(xué)生信息,使用指向結(jié)構(gòu)體類型數(shù)組的指針及相關(guān)算法查找出學(xué)生信息中成績(jī)最低學(xué)生的信息。2024/12/23243.?C語言代碼#include<stdio.h>#include<string.h>structstudent{intsnum;charsname[20];floatscore;chargrade;}stud[]={{18091210,"ZHaolei",90.3,'A'},{18091220,"SunxiaoYang",85,'B'},{18091230,"Wanle",76.5,'C'}},*pstu1;/*利用結(jié)構(gòu)體數(shù)組初始化保存3個(gè)學(xué)生信息,同時(shí)建立指針變量*/main(){unsignedlongintstu_len=sizeof(stud)/sizeof(stud[0]);/*計(jì)算數(shù)組長(zhǎng)度*/inti;floatmin;pstu1=stud; /*指針變量pstu1獲得數(shù)組首地址*/pstu1=pstu1+stu_len; /*指針變量pstu1指向第4個(gè)結(jié)構(gòu)體數(shù)組元素地址,增加一個(gè) 新數(shù)組元素*/pstu1->snum=18191121; /*指針變量pstu1對(duì)結(jié)構(gòu)體中的成員的賦值(數(shù)組第4個(gè)元素)*/

strcpy((*pstu1).sname,"LihanYang");

pstu1->score=67.5;

pstu1->grade='D';pstu1=stud; /*指針變量pstu1重新獲得數(shù)組首地址*/min=pstu1->score; /*指針pstu1對(duì)成員的引用,將數(shù)組第一個(gè)元素中的score

假設(shè)為最低成績(jī)*/

for(i=1;i<(stu_len+1);i++)

{++(pstu1); /*指針變量pstu1增1*/if(pstu1->score<min) /*指針變量pstu1所指score的值小于假設(shè)的score*/min=pstu1->score; /*指針變量pstu1所指score的值賦值給min*/}printf("Theninformationofthestudentis:\n");printf("snum=%d,sname=%s,minscore=%f,grade=%c\n",pstu1->snum,pstu1->sname,pstu1->

score,pstu1->grade);}2024/12/23254.程序運(yùn)行結(jié)果Theninformationofthestudentis:snum=18191121,sname=LihanYang,minscore=67.500000,grade=D2024/12/23266.3結(jié)構(gòu)體與指針

指針可以指向變量和數(shù)組,指針同樣可以指向結(jié)構(gòu)體變量和結(jié)構(gòu)體數(shù)組。2024/12/23276.3.1指向結(jié)構(gòu)體變量的指針

結(jié)構(gòu)體變量首字節(jié)地址即為結(jié)構(gòu)體變量指針,可以使用指針訪問結(jié)構(gòu)體變量中的成員。1.結(jié)構(gòu)體變量指針定義格式與賦值結(jié)構(gòu)體指針變量定義格式如下:struct結(jié)構(gòu)體類型名*結(jié)構(gòu)體指針變量名結(jié)構(gòu)體指針變量定義后,系統(tǒng)僅為指針變量分配存儲(chǔ)結(jié)構(gòu)體類型的起始地址。指針變量賦值后,結(jié)構(gòu)體指針變量才能對(duì)結(jié)構(gòu)體成員進(jìn)行操作。結(jié)構(gòu)體指針變量賦值方式一:先定義結(jié)構(gòu)體變量,再定義結(jié)構(gòu)體指針變量。2024/12/2328例如:structstudentstu1structstudent*pu=&stu1或structstudentstu1,*pstu;pstu=&stu1結(jié)構(gòu)體指針變量賦值方式二:如果沒有定義結(jié)構(gòu)體變量,可以使用分配內(nèi)存函數(shù)malloc()按以下方式對(duì)結(jié)構(gòu)體指針變量賦值。例如:structstudent*pstu=(structstudent*)malloc(sizeof(structstudent));說明:(1)不可以使用結(jié)構(gòu)體類型名對(duì)結(jié)構(gòu)體指針變量賦值,例如:pstu=&student。(2)可以把成員定義為本結(jié)構(gòu)體相同的結(jié)構(gòu)體指針變量。2024/12/2329例如:structstudent{intsnum;structstudent*point;}結(jié)構(gòu)體含有一個(gè)指向自己的結(jié)構(gòu)體指針變量,這種結(jié)構(gòu)體在鏈表、樹和有向圖中廣泛應(yīng)用。2024/12/23302.結(jié)構(gòu)體指針變量對(duì)成員的引用結(jié)構(gòu)體指針變量對(duì)成員的引用形式有兩種。(*結(jié)構(gòu)體指針變量).成員名或結(jié)構(gòu)體指針變量->成員名2024/12/2331例6.2使用結(jié)構(gòu)體指針變量輸出學(xué)生信息中的姓名、成績(jī)和成績(jī)等級(jí)。#include<string.h>#include<stdio.h>structstudent{charsname[10];intsnum;floatscore;chargrade;}stu1={"ZhaoLei",18091223,92.5,'A'},*pstu1;main(){pstu1=&stu1;strcpy((*pstu1).sname,"LiJie");/*為結(jié)構(gòu)體變量重新賦值*/(*pstu1).score=82;pstu1->grade='B';printf("snameis%s\n",&(*pstu1).sname);

printf("scoreis%f\n",pstu1->score);printf("gradeis%c\n",(*pstu1).grade);}2024/12/2332程序運(yùn)行結(jié)果如下:snameisLiJiescoreis82.000000gradeisB2024/12/23336.3.2指向結(jié)構(gòu)體類型數(shù)組的指針

以基本數(shù)據(jù)類型建立的數(shù)組的首地址是指針,可以使用指針變量對(duì)數(shù)組中的基本數(shù)據(jù)類型元素進(jìn)行賦值和操作。同樣指針類型也可以運(yùn)用于結(jié)構(gòu)體數(shù)組,即指向結(jié)構(gòu)體類型數(shù)組的指針。1.指向結(jié)構(gòu)體數(shù)組指針定義與賦值定義指向結(jié)構(gòu)體數(shù)組指針變量和之前定義數(shù)組的指針的方法是一樣的。例如,案例三中在定義結(jié)構(gòu)體數(shù)組的同時(shí)定義指向結(jié)構(gòu)體數(shù)組的指針,通過pstu1=stud使得指針變量獲得數(shù)組首地址。2.結(jié)構(gòu)體數(shù)組指針引用結(jié)構(gòu)體成員與之前數(shù)組成員的引用方式相同,結(jié)構(gòu)體數(shù)組指針對(duì)結(jié)構(gòu)體數(shù)組成員的引用方式有地址法、指針法、指針的數(shù)組表示法。例如,案例三中通過指針法pstu1->score方式完成對(duì)成員的數(shù)據(jù)操作。2024/12/2334指向結(jié)構(gòu)體類型數(shù)組的指針的使用與指向基本數(shù)據(jù)類型的指針使用相同,pstu1++?和++pstu1可以使pstu1指向結(jié)構(gòu)體數(shù)組的下一個(gè)元素地址。使用指向結(jié)構(gòu)體數(shù)組的指針,請(qǐng)注意以下表達(dá)式的含義:(1)因?yàn)椤?>”運(yùn)算符優(yōu)先級(jí)最高,所以pstu1->snum,pstu1->snum++,++pstu1->snum三個(gè)表達(dá)式都是對(duì)成員變量snum的操作。(2)?(++pstu1)->snum,先使pstu1加1,指向下一個(gè)數(shù)組元素地址,然后得到該元素的snum成員的值。(3)?pstu1++->snum,先得到pstu1所指的snum的值,然后使pstu1加1,指向該數(shù)組下一個(gè)元素地址。2024/12/2335案例四結(jié)構(gòu)體函數(shù)的使用1.問題描述根據(jù)學(xué)生成績(jī),判斷學(xué)生成績(jī)的等級(jí)。(例如成績(jī)score,當(dāng)90≤score≤100時(shí)等級(jí)為A,80≤score<90時(shí)等級(jí)為B)。2.問題分析學(xué)生成績(jī)?cè)O(shè)定為結(jié)構(gòu)體變量或結(jié)構(gòu)體數(shù)組,通過函數(shù)使學(xué)生成績(jī)對(duì)應(yīng)轉(zhuǎn)換成等級(jí)。2024/12/23363.?C語言代碼#include"stdio.h"#include"string.h"structstudent{intnum;charname[15];floatscore;chargrade;}stu={18091221,"ZhangMing",75.5},/*結(jié)構(gòu)體變量,其中成員grade未賦值*/stu1[]={{18091213,"LiJian",80},{18091223,"SunQiang",68},{18091231,"ZhaoShaSha",95.5}}; /*結(jié)構(gòu)體數(shù)組,其中成員grade未賦值*//*函數(shù)Dengji對(duì)結(jié)構(gòu)體變量stu中成員grade賦值*/Dengji(structstudent*s) /*形參s為指向結(jié)構(gòu)體變量的指針,程序運(yùn)行后s的值為具有相同結(jié)構(gòu)體變量實(shí)參的地址*/{if(s->score>=60&&s->score<70)s->grade='D';/*地址傳遞,在形參s->grade賦值后,對(duì)應(yīng)實(shí)參stu.grade有相同的值*/if(s->score>=70&&s->score<80)s->grade='C';if(s->score>=80&&s->score<90)s->grade='B';if(s->score>=90&&s->score<=100)s->grade='A';}2024/12/2337voidmain(){inti;printf("結(jié)構(gòu)體變量stu原始數(shù)據(jù)為\n");printf("num=%d,name=%s,score=%f,grade=%c\n",stu.num,,stu.score,stu.grade);Dengji(&stu);/*調(diào)用函數(shù)Dengji完成結(jié)構(gòu)體變量stu中g(shù)rade賦值,使用地址傳遞*/printf("結(jié)構(gòu)體變量stu成員成績(jī)等級(jí)賦值后數(shù)據(jù)為\n");printf("num=%d,name=%s,score=%f,grade=%c\n",stu.num,,stu.score,stu.grade);printf("\n");printf("結(jié)構(gòu)體數(shù)組stu1[]原始數(shù)據(jù)為\n");for(i=0;i<3;i++)printf("num=%d,name=%s,score=%f,grade=%c\n",stu1[i].num,stu1[i].name,stu1[i].score,stu1[i].grade);printf("\n");printf("結(jié)構(gòu)體數(shù)組stu1[]元素中成員成績(jī)等級(jí)賦值后數(shù)組數(shù)據(jù)為\n");for(i=0;i<3;i++)Dengji(&stu1[i]);/*調(diào)用函數(shù)Dengji完成結(jié)構(gòu)體數(shù)組每個(gè)元素中g(shù)rade賦值,使用地址傳遞*/for(i=0;i<3;i++)printf("num=%d,name=%s,score=%f,grade=%c\n",stu1[i].num,stu1[i].name,stu1[i].score,stu1[i].grade);}2024/12/23384.程序運(yùn)行結(jié)果結(jié)構(gòu)體變量stu原始數(shù)據(jù)為num=18091221,name=ZhangMing,score=75.500000,grade=結(jié)構(gòu)體變量stu成員成績(jī)等級(jí)賦值后數(shù)據(jù)為num=18091221,name=ZhangMing,score=75.50000,grade=C結(jié)構(gòu)體數(shù)組stu1[]原始數(shù)據(jù)為num=18091213,name=LiJian,score=80.000000,grade=num=18091223,name=SunQiang,score=68.000000,grade=num=18091231,name=ZhaoShaSha,score=95.500000,grade=結(jié)構(gòu)體數(shù)組stu1[]元素中成員成績(jī)等級(jí)賦值后數(shù)組數(shù)據(jù)為num=18091213,name=LiJian,score=80.000000,grade=Bnum=18091223,name=SunQiang,score=68.000000,grade=Dnum=18091231,name=ZhaoShaSha,score=95.500000,grade=A2024/12/23396.4結(jié)構(gòu)體與函數(shù)

結(jié)構(gòu)體類型數(shù)據(jù)也可以作為函數(shù)的參數(shù)用于程序的設(shè)計(jì),參數(shù)為結(jié)構(gòu)體的函數(shù)稱為結(jié)構(gòu)體函數(shù),使用結(jié)構(gòu)體作為函數(shù)參數(shù),可以提高數(shù)據(jù)傳輸效率。結(jié)構(gòu)體類型的變量或者結(jié)構(gòu)體類型的數(shù)組傳遞給函數(shù)有以下三種方式:(1)結(jié)構(gòu)體成員作為參數(shù)。這與普通變量作為參數(shù)一樣,是值傳遞;(2)結(jié)構(gòu)體變量作為函數(shù)參數(shù)。要求形參和實(shí)參是同一種結(jié)構(gòu)體類型變量,傳遞時(shí)采用的也是值傳遞的方式。這種調(diào)用方式首先形參要分配存儲(chǔ)空間,其次實(shí)參將各成員的值依次賦值給形參的對(duì)應(yīng)成員。如果成員比較多,在時(shí)間和空間上都增加了系統(tǒng)開銷;(3)結(jié)構(gòu)體變量的地址或結(jié)構(gòu)體數(shù)組名為參數(shù)。形參接受實(shí)參地址,這種情況屬于地址傳遞。例如,案例四中函數(shù)Dengji中參數(shù)采用的就是結(jié)構(gòu)體變量地址為參數(shù),是地址傳遞。2024/12/23406.4.1指向結(jié)構(gòu)體變量的指針作為函數(shù)參數(shù)

函數(shù)參數(shù)傳遞方式有數(shù)值傳遞和地址傳遞,數(shù)值傳遞形參的改變不會(huì)影響到實(shí)參。如果想在調(diào)用函數(shù)中改變主調(diào)函數(shù)中的實(shí)參,可以用結(jié)構(gòu)體變量的地址(或數(shù)組成員地址)作為實(shí)參,用指向相同結(jié)構(gòu)體類型的結(jié)構(gòu)體指針作為函數(shù)的形參來傳遞地址值,以地址傳遞的方式改變實(shí)參的數(shù)據(jù)值。例如,案例四中結(jié)構(gòu)體變量stu在初始化時(shí)成員grade未賦值(實(shí)際值為0,輸出時(shí)為空字符),通過傳地址方式的函數(shù)調(diào)用在函數(shù)中完成了grade賦值,在主函數(shù)中輸出grade變量的值;案例四中結(jié)構(gòu)體數(shù)組stu1[]元素中的成員通過地址傳遞的方式,完成了數(shù)組元素中成員變量grade的賦值。2024/12/23416.4.2結(jié)構(gòu)體變量作為函數(shù)的返回值

結(jié)構(gòu)體變量可以作為函數(shù)的返回值,返回值為結(jié)構(gòu)體類型的函數(shù)稱為結(jié)構(gòu)體函數(shù)。結(jié)構(gòu)體變量作為函數(shù)的返回值的定義格式:struct結(jié)構(gòu)體名函數(shù)名(struct結(jié)構(gòu)體名參數(shù))形參、實(shí)參數(shù)、和函數(shù)均采用相同結(jié)構(gòu)體類型。例6.3完成學(xué)生基本信息的錄入,并根據(jù)學(xué)生的學(xué)號(hào)輸出學(xué)生的信息。#include<stdio.h>#defineN3structstudent{intnum;charname[15];floatscore;}stu[N];/*函數(shù)search完成對(duì)應(yīng)學(xué)號(hào)的學(xué)生信息查詢并返回學(xué)生信息,形參變量p和函數(shù)具有相同的結(jié)構(gòu)體類型,形參m是學(xué)號(hào)*/structstudent*search(structstudent*p,intm){structstudent*s=NULL;for(;p<(stu+N);p++)if(p->num==m){s=p;break;}returns;/*返回查詢到的地址,否則為NULL*/}/*函數(shù)完成學(xué)生信息的輸入,參數(shù)p獲得數(shù)組s1[]地址,參數(shù)n獲得數(shù)據(jù)元素個(gè)數(shù)N*/voidinput(structstudent*p,intn){inti;printf("NumNameScore\n");for(i=0;i<n;i++){scanf("%d",&p[i].num);scanf("%s",p[i].name);

scanf("%f",&p[i].score);}}2024/12/2342/*函數(shù)完成學(xué)生信息的輸出,參數(shù)s1[]為數(shù)組地址*/voidoutput(structstudents1){printf("NumNameScore\n");printf("%d,%s,%f\n",s1.num,,s1.score);}main(){intn;structstudent*s1=stu;input(s1,N);/*函數(shù)調(diào)用:完成學(xué)生信息輸入,參數(shù)數(shù)組名s1(地址傳遞),數(shù)組元素個(gè)數(shù)N(值傳遞)傳遞給函數(shù)input*/printf("請(qǐng)輸入查找學(xué)生的學(xué)號(hào):\n");scanf("%d",&n);s1=search(s1,n);/*函數(shù)調(diào)用:完成學(xué)生信息查詢,參數(shù)數(shù)組名s1(地址傳遞),參數(shù)n學(xué)號(hào)(數(shù)值傳遞)*/if(s1!=NULL)output(*s1);/*函數(shù)調(diào)用:完成學(xué)生信息輸出,參數(shù)*s1(值傳遞)*/elseprintf("未查找到該學(xué)生");}2024/12/2343程序運(yùn)行結(jié)果如下:NumNameScore18090212LiLu8718090109ZhaoJie7518090328SunJiaJun92請(qǐng)輸入查找學(xué)生的學(xué)號(hào):1809032818090328SunJiaJun92.0000002024/12/2344案例五共用體變量設(shè)計(jì)與使用1.問題描述描述若干教師的業(yè)績(jī),每個(gè)教師包括編號(hào)、姓名、職稱、業(yè)績(jī);若職稱是講師,則業(yè)績(jī)描述為其講述的課程門數(shù);若職稱為教授,業(yè)績(jī)描述為科研項(xiàng)目的金額。2.問題分析教師數(shù)據(jù)中的編號(hào)、姓名、職稱是三個(gè)固定字段,分別用整型、字符數(shù)組、字符數(shù)組來存儲(chǔ),業(yè)績(jī)可能是講述的課程門數(shù)或科研項(xiàng)目的金額,二選一,用共用體類型描述。觀察共用體變量定義、賦值方法。2024/12/23453.?C語言代碼/*本程序?qū)崿F(xiàn)不同職稱教師的業(yè)績(jī)管理*/#include<stdio.h>#include<string.h>#defineTnum3 /*教師的數(shù)量*/unionyeji/*教師業(yè)績(jī)共用體定義*/{intkechengnum; /*講述課程門數(shù)*/floatkeyanjine; /*科研項(xiàng)目金額*/};structteacher /*教師結(jié)構(gòu)體定義*/{intTid; /*教師編號(hào)*/charTname[20]; /*教師姓名*/charTrank[20]; /*教師職稱*/unionyejiachievement; /*教師業(yè)績(jī),為共用體類型變量*/}Teacher[Tnum]; /*存儲(chǔ)教師信息數(shù)組,為全局的結(jié)構(gòu)體類型的數(shù)組*/2024/12/2346voidmain(){inti; /*i循環(huán)控制變量*/printf("請(qǐng)輸入教師信息:\n");for(i=0;i<Tnum;i++) /*循環(huán)輸入教師信息*/{/*循環(huán)輸入教師固定字段信息*/scanf("%d%s%s",&Teacher[i].Tid,Teacher[i].Tname,Teacher[i].Trank); if(strcmp(Teacher[i].Trank,"jiangshi")==0) /*是講師則輸入課程數(shù)量*/scanf("%d",&Teacher[i].achievement.kechengnum);elseif(strcmp(Teacher[i].Trank,"jiaoshou")==0) /*是教授則輸入項(xiàng)目金額*/scanf("%f",&Teacher[i].achievement.keyanjine);else /*職稱輸入錯(cuò)誤的提示信息*/printf("dataerror!\n");}printf("編號(hào)\t姓名\t職稱\t\t講授課程或項(xiàng)目金額\n");for(i=0;i<Tnum;i++) /*循環(huán)輸出教師信息*/{printf("%d\t%s\t%s\t",Teacher[i].Tid,Teacher[i].Tname,Teacher[i].Trank);if(strcmp(Teacher[i].Trank,"jiangshi")==0)printf("%d\n",Teacher[i].achievement.kechengnum);elseif(strcmp(Teacher[i].Trank,"jiaoshou")==0)printf("%f\n",Teacher[i].achievement.keyanjine);

else

printf("dataerror!\n");}}2024/12/23474.程序運(yùn)行結(jié)果請(qǐng)輸入教師信息:1000wangjiangshi51001lijiaoshou9.81002zhaojiaoshou10.85編號(hào)姓名職稱講授課程或項(xiàng)目金額1000wangjiangshi51001lijiaoshou9.8000001002zhaojiaoshou10.8500002024/12/23486.5共用體

共用體是一種與結(jié)構(gòu)體類似的構(gòu)造類型,可以包括數(shù)目固定、類型不同的若干數(shù)據(jù),所有成員共享一段公共存儲(chǔ)空間(如案例五中類型unionyeji)。所謂共享不是指把多個(gè)成員同時(shí)裝入一個(gè)共用體變量?jī)?nèi),而是指該共用體變量可被賦予任一成員值,但每次只能給其中的一個(gè)變量賦值,新賦的值會(huì)覆蓋原有變量。也就是某一時(shí)刻共用體的成員變量只能有一個(gè)有正確的值。共用體類型變量所占內(nèi)存空間不是各個(gè)成員所需存儲(chǔ)空間字節(jié)數(shù)的總和,而是共用體成員中存儲(chǔ)空間最大的成員所要求的字節(jié)數(shù)。共用體用途:使幾個(gè)不同類型的變量共占一段內(nèi)存(相互覆蓋)。2024/12/23496.5.1共用體類型的定義

與結(jié)構(gòu)體類型的定義類似,定義一個(gè)共用體類型的一般形式為union共用體名{數(shù)據(jù)類型成員名1;數(shù)據(jù)類型成員名2;...數(shù)據(jù)類型成員名n;};成員列表中含有若干成員,成員名的命名應(yīng)符合標(biāo)識(shí)符的規(guī)定,彼此之間不能相同。例如:uniondata{inti;charch[10];};定義了一個(gè)名為uniondata的共用體類型,它包含有兩個(gè)成員,一個(gè)為整型,成員名為i;另一個(gè)為字符數(shù)組,數(shù)組名為ch。共用體定義之后,即可進(jìn)行共用體變量說明。被說明為uniondata類型的變量,可以存放整型量i或存放字符數(shù)組ch,這兩種數(shù)據(jù)類型的成員共享同一塊內(nèi)存空間。共用體變量任何時(shí)刻只有一個(gè)成員存在。2024/12/23506.5.2共用體變量的定義

共用體變量的說明和結(jié)構(gòu)體變量的定義類似,也有三種形式。(1)定義共用體類型的同時(shí)定義共用體類型變量:uniondata{shortinti;

charch;floatf;}a,b;(2)先定義共用體類型,再定義共用體類型變量:uniondata{shortinti;charch;floatf;};uniondataa,b,c,*p,d[3];(3)直接定義共用體類型變量:union圖6.1共用體變量的存儲(chǔ){shortinti;charch;

floatf;}a,b,c;2024/12/2351在內(nèi)存分配時(shí),a、b、c變量的長(zhǎng)度等于uniondata成員中最長(zhǎng)的長(zhǎng)度,即等于實(shí)數(shù)f的長(zhǎng)度,共4個(gè)字節(jié)。a、b、c變量如果賦予字符型ch值時(shí),只使用了1個(gè)字節(jié),而賦予f時(shí),可用4個(gè)字節(jié)。a在內(nèi)存中的存儲(chǔ)情況如圖6.1所示。2024/12/2352圖6.1共用體變量的存儲(chǔ)2024/12/23536.5.3共用體變量的引用

引用共用體變量的成員方式與結(jié)構(gòu)體非常類似,方式有下面幾種:(1)在定義了共用體變量之后,可以使用“.”運(yùn)算符來引用它的成員。例如:a.i=5;(2)可以把共用體變量的地址賦值給同類型的指針變量,可以利用指向共用體變量的指針來引用它的成員。例如:uniondata{shortinti;charch;floatf;}a,b,c,*p,d[3];p=&a;(*p).i=9;等價(jià)于p->i=9;。2024/12/2354(3)共用體變量也可以初始化,但只是對(duì)它的成員表中的第一個(gè)成員進(jìn)行初始化,不能對(duì)它所有列出的成員都賦初值。例如:uniondata{shortinti;charch;floatf;}a={8};將它的第一個(gè)成員i初始化成了8。2024/12/2355注意:①由于共用體變量的各個(gè)成員占用同一段內(nèi)存空間,因此它們的起始地址都是相同的。所以,&a.i、&a.ch、&a.f與&a的值都是相同的,不過,這些地址的類型是不同的。②在任意一個(gè)時(shí)刻分配給共用體變量的內(nèi)存空間中,最多只能保留共用體變量的一個(gè)成員的值。當(dāng)為共用體變量的某個(gè)成員賦值時(shí),該值將覆蓋掉該共用體變量中在此之前保存的其他成員的值。因此在某個(gè)時(shí)刻聯(lián)合變量存儲(chǔ)空間中將保留最后一個(gè)被賦值的成員的值。2024/12/2356例6.4輸出共用體變量成員的值。#include"stdio.h"uniondata /*定義一個(gè)共用體類型data*/{shortintstud;charteach[2];};main(){uniondataun1;

un1.stud=2;un1.teach[0]=23;un1.teach[1]=0;printf("%hd\n",un1.stud);}2024/12/2357程序運(yùn)行結(jié)果如下:23共用體變量un1中的成員stud和數(shù)組成員teach都是從內(nèi)存空間的同一個(gè)位置開始存儲(chǔ),因?yàn)槎陶蛃tud與數(shù)組teach的前兩個(gè)元素共用一個(gè)2個(gè)字節(jié)的存儲(chǔ)單元,所以數(shù)組前2個(gè)元素的值覆蓋了最初給成員stud的值。共用體的類型可以出現(xiàn)在結(jié)構(gòu)體類型的定義中,結(jié)構(gòu)體也可以作為共用體的成員出現(xiàn)。共用體類型變量不能作為函數(shù)參數(shù)或者函數(shù)的返回值,但是可以使用指向共用體類型變量的指針來傳遞數(shù)據(jù)。2024/12/23586.6枚舉類型如果一個(gè)變量只有幾種可能的值,可以定義為枚舉類型。1.什么是枚舉所謂“枚舉”,是指將變量的值一一列舉出來,變量的值在列舉出來的值的范圍內(nèi)。枚舉數(shù)據(jù)是一個(gè)被命名為整型常數(shù)的集合,這些常數(shù)指定了所有已被定義的各種合法值。枚舉在日常生活中十分常見,如一周分為7天:sun,mon,tue,wed,thu,fri,sat可按如下格式定義為枚舉類型:enumday{sun,mon,tue,wed,thu,fri,sat};關(guān)鍵字enum表示定義一個(gè)枚舉類型。2024/12/23592.枚舉類型的定義和枚舉變量的定義先定義枚舉類型,再定義枚舉變量。枚舉類型定義的一般形式為enum枚舉類型名{枚舉表};其中,enum是定義枚舉類型的關(guān)鍵字;“枚舉表”由多個(gè)用戶自定義的標(biāo)識(shí)符組成,標(biāo)識(shí)符之間用逗號(hào)分開。枚舉變量定義的一般形式為enum枚舉類型名枚舉變量表;例如:定義一個(gè)稱之為day的枚舉類型,并說明today是屬于該類型的一個(gè)變量:enumday{sun,mon,tue,wed,thu,fri,sat};/*枚舉類型的定義*/enumdaytoday;/*和枚舉變量的定義*/枚舉變量的定義也有和結(jié)構(gòu)體共用體類似的三種形式,這里不再一一列舉。2024/12/2360說明:(1)花括號(hào)中的內(nèi)容稱為枚舉表,每個(gè)枚舉表項(xiàng)是整型常數(shù),系統(tǒng)默認(rèn)規(guī)定其值依次為0,1,2,3,4,5,6。在定義枚舉類型時(shí)也可對(duì)枚舉表項(xiàng)進(jìn)行初始化以改變它們的值。例如:enumday{sun=1,mon,tue=5,wed,thu,fri,sat=11};則sun=1,mon=2,tue=5,wed=6,thu=7,fri=8,sat=11,如果某個(gè)枚舉元素沒有初始化,會(huì)自動(dòng)取前一個(gè)枚舉元素值加1,第一個(gè)枚舉元素自動(dòng)取0。(2)枚舉元素都是常量,即枚舉常量,而不是變量,因此不能為枚舉元素賦值,如sun=5,mon=8是錯(cuò)誤的。枚舉元素可用于給枚舉變量賦值,而枚舉變量不能接收一個(gè)非枚舉常量的賦值。例如:today=sun;(正確)today=3;(錯(cuò)誤)(3)可以將一個(gè)整數(shù)經(jīng)強(qiáng)制類型轉(zhuǎn)換后賦給枚舉變量。例如:enumday{sun,mon,tue,wed,thu,fri,sat}today;today=(enumday)3;相當(dāng)于today=wed;2024/12/23613.定義枚舉類型的好處(1)用標(biāo)識(shí)符表示數(shù)值增加了程序的可讀性(直觀)。例如,if(today==sat)nextday=sun;就比較清晰,if(today==6)nextday=7;就不如前者清晰。(2)可限制了變量的取值范圍。在上面的例子中,today只能取sun~sat中的值,不能隨便取值。2024/12/2362例6.5順序輸出5種顏色名。#include"stdio.h"main(){

enumcolor{red,yellow,blue,white,black};

enumcolorc;

for(c=red;c<=black;c++)

switch(c)

{

case

red:

printf(″red″);

break;

case

yellow:

printf(″yellow″);

break;

case

blue:

printf(″blue″);

break;

case

white:

printf(″whi

溫馨提示

  • 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. 人人文庫(kù)網(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)論