




版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
1
C語言程序設計任務式教程(微課版)
VisualC++模塊6組合數(shù)據(jù)類型任務1結構體任務2共用體任務3枚舉3計算機工程學院模塊6組合數(shù)據(jù)類型任務1結構體學習目標掌握結構體類型的說明、結構體變量的定義及初始化方法、掌握結構體變量成員的引用、結構體數(shù)組的使用、領會存儲動態(tài)分配和釋放。4計算機工程學院6.1.1案例講解案例1學生信息的描述1.問題描述
假定一個學生的信息包括學號,姓名,成績,在數(shù)據(jù)處理中,我們通常把一個學生信息作為整體,編程構造一個學生信息類型,并實現(xiàn)其輸入,輸出。2.編程分析
(1)C語言中的結構體類型可以將不同類型的信息組織成一個整體,構造出一種新的類型,這里我們可以構造學生類型,學生是我們處理信息的基本單位。5計算機工程學院
(2)新構造的類型沒有對應的輸入,輸出格式控制符,需要把學生類型包含的各個成員分別輸出,可以定義函數(shù)來實現(xiàn)學生信息的輸入和輸出。3.編寫源程序#include<stdio.h>structstudent{ intnumber; charname[10]; floatscore;};6計算機工程學院voidprintStu(structstudent*p);
structstudentinputStu();voidmain(){
structstudentstu1;
printf("請輸入一個學生的信息(學號姓名成績)\n");
stu1=inputStu();
printf("結構體變量中的內(nèi)容是:\n");
printStu(&stu1);}voidprintStu(structstudent*p)7計算機工程學院{printf("%d%s%f\n",p->number,p->name,p->score);}structstudentinputStu(){ structstudentstu;scanf("%d%s%f",&stu.number,,&stu.score); returnstu;
}8計算機工程學院4.程序運行結果圖6-1案例1運行結果9計算機工程學院5.歸納分析
(1)結構體類型定義在函數(shù)外面,它的使用范圍是全局的,以便所有的函數(shù)都可以使用。(2)stu1是結構體變量,它的類型是structstudent,stu1包含3個成員:學號,姓名,成績,變量占用的存儲空間大小sizeof(stu1)=sizeof(number)+sizeof(name)+sizeof(score),若要表示這個學生的成績是90分,可以寫成:stu1.score=90,“.”在這里是一個運算符。
10計算機工程學院(3)程序中還用到了結構體指針:structstudent*p,并且這個指針作為函數(shù)的參數(shù),根據(jù)參數(shù)的傳遞,p=&stu1,使用指針操作結構體變量中的成員有兩種寫法:p->score或(*p).score,它們的值與stu1.score相等。11計算機工程學院案例2職工信息的查詢1.問題描述有6個職工的信息,其中每個職工信息包括編號、姓名、工資,請找到工資最高的職工并輸出其信息。2.編程分析
(1)把編號,姓名,工資組合成一個整體,作為新的數(shù)據(jù)類型,用這個類型定義長度為6的數(shù)組,再利用數(shù)組中查找最大值的算法來解決問題。12計算機工程學院
(2)偽代碼如下:定義結構體:職工
voidmain(){定義結構體數(shù)組用于保存6個職工信息;定義變量i用于控制循環(huán)次數(shù);定義變量k記錄工資最高的職工;循環(huán)輸入6個職工的信息;設k的初值為0(從第0位職工開始找);循環(huán)變量i=1;循環(huán)比較大小:13計算機工程學院
{如果第i個職工的工資>第k個職工的工資
k=i;
}輸出第k個(即工資最高的)職工的信息;
}3.編寫源程序#include<stdio.h>
structworker{intnumber;
14計算機工程學院charname[20];floatpay;};voidmain(){
structworkerw[6];inti,k;printf("輸入6個員工信息\n");printf("編號姓名工資\n");for(i=0;i<6;i++){15計算機工程學院scanf("%d%s%f",&w[i].number,w[i].name,&w[i].pay);}k=0;i=1;while(i<6)
{
if(w[i].pay>w[k].pay)k=i;i++;
}
printf("工資最高的人員信息是:\n");
printf("%d\t%s\t%f\n",w[k].number,w[k].name,w[k].pay);}16計算機工程學院4.程序運行結果圖6-2案例2運行結果17計算機工程學院5.歸納分析結構體類型的名稱是structworker,用結構體類型來定義結構體變量或結構體數(shù)組。w是長度為6的數(shù)組,存放6個員工的信息,那么第一個員工就是w[0],第六個員工就是w[5],第一個員工的工資表示為:w[0].pay,第一個員工的姓名是:w[0].name;輸入或輸出第i個員工的信息時不能對w[i]整體進行操作,用格式控制符%d對應w[i].number,%s對應w[i].name,%f對應w[i].pay,因為number是int型的,name是字符串,pay是float型數(shù)據(jù)。18計算機工程學院查找最大值時第k個員工就是工資最高的人員,如果有人的工資比第k個員工還高,那么更新最高紀錄k,這使得k始終是工資高的員工的下標。19計算機工程學院6.1.2基礎理論
在前面學習的各種數(shù)據(jù)類型包括數(shù)組在內(nèi),都只能存放同類型的數(shù)據(jù)。而在日常的數(shù)據(jù)處理中,我們經(jīng)常需要將若干不同類型的數(shù)據(jù)組合起來,作為一個整體進行處理。例如一個學生的數(shù)據(jù)信息有:學號、姓名、性別、成績、家庭住址等,這些信息分別具有整型、字符型、實型等不同的類型。20計算機工程學院
C語言提供的結構體(structure)或稱之為“結構”類型,就可將這些不同類型的信息組織成一個整體。
“結構體”是由若干“成員”(數(shù)據(jù)信息)組成的一種構造類型。每一個成員可以是一個基本數(shù)據(jù)類型或者又是一個構造類型,結構體就是一種“構造”而成的數(shù)據(jù)類型。21計算機工程學院1.結構體類型的定義結構體類型定義的一般形式:
struct<結構體名>{<成員表列>};其中struct是定義結構體類型的關鍵字,<結構體名>由用戶根據(jù)標識符的命名規(guī)則進行命名,成員表列由結構體中各個成員組成。例如:22計算機工程學院
structstudent{longnum;/*學生的學號*/charname[20];/*學生的名字*/charsex;/*性別*/floatscore;/*成績*/};在這個結構體定義中,結構體名為student,該結構體由4個成員組成。第一個成員num為整型變量;第二個成員name為字符數(shù)組;第三個成員sex為字符變量;第四個成員score為實型變量。這四個成員組成的成員表列就是結構體structstudent的成員信息。23計算機工程學院定義結構體時的注意事項:
(1)結構體名字符合標識符的規(guī)則,盡量取有實際意義的標識符。(2)注意大括號外的分號,不能少。(3)結構體成員可以是任何的基本數(shù)據(jù)類型變量,也可以是數(shù)組、指針類型的變量,還允許是其它類型的結構體變量。例如:24計算機工程學院structdata{intyear;/*年*/intmonth;/*月*/intday;/*日*/};structstudent{longnum;/*學生的學號*/charname[20];/*學生的名字*/charsex;/*性別*/
structdatabirthday;floatscore;/*成績*/};25計算機工程學院
在structstudent這個結構體中又包含了birthday這個結構體變量,形成了結構體的嵌套定義形式。2.結構體變量的說明和其它類型的變量一樣,結構體類型的變量也須先說明。結構體變量的說明有四種方法:
(1)先定義結構體類型,再說明結構體變量。一般形式為:
struct結構體名變量名表列;例如:26計算機工程學院
structstudent/*定義結構體類型*/{longnum;
charname[20];
charsex;
floatscore;};
structstudentstudent1,student2;/*說明結構體變量*/在本例中說明了兩個structstudent類型的結構體變量student1,student2。變量名之間用逗號隔開。注意在定義結構體時,系統(tǒng)沒有為其分配內(nèi)存空間,只有在進行具體的變量說明時才為變27計算機工程學院
量分配內(nèi)存空間。即在本例中系統(tǒng)不為結構體structstudent分配內(nèi)存空間,只為變量student1和student2分配空間。如圖6-3所示:
student1:
student2:圖6-3結構體變量
(2)在定義結構體的同時說明結構體變量。一般形式為:2003001LiPingM91.52003001ZhaoQiangF89.028計算機工程學院
struct結構體名{成員表列}變量名表列;
例如:structstudent{longnum;
charname[20];
charsex;
floatscore;}student1,student2;29計算機工程學院(3)利用無名結構說明結構體變量。一般形式為:
struct{
成員表列;}變量名表列;例如:struct{longnum;charname[20];charsex;floatscore;}student1,student2;30計算機工程學院這種方法同樣說明了兩個結構體變量student1和student2,但在程序的其他地方(例如在函數(shù)內(nèi)部)不可以使用這種結構體來說明其它的變量,因此這種方法使用的比較少。
(4)利用重命名類型(typedef)說明結構體在C語言中允許用戶自己定義類型說明符,即利用類型定義符typedef為數(shù)據(jù)類型取“別名”。一般形式為:
typedef已定義的類型標識符新標識符;作用:利用新標識符代替原來已定義的類型標識符。31計算機工程學院例如:typedefintINTEGER;
typedeffloatREAL;分別用INTEGER和REAL代替系統(tǒng)中已存在的int和float類型,就可以利用它們說明新的變量。例如:INTEGERa,b;
REALc,d;下面利用typedef說明結構體,例如:32計算機工程學院先定義新類型名:typedefstruct{
longnum;
charname[20];
charsex;
floatscore;}STUD;說明新的結構體變量:STUDstudent1,student2;關于typedef需要注意的是它不是創(chuàng)建新的類型,只是為標識符取一個別名,使以后的使用更加靈活方便。33計算機工程學院3.結構體的引用與初始化結構體被說明后就可以在程序中引用它,對結構體變量的使用是通過對其成員的引用來實現(xiàn)的。引用結構體變量的常用方式是利用“.”(成員分量)運算符,一般形式為:
<結構體變量名>.<成員名>例如下列語句:student1.num=2003001;strcpy(,"LiPing");/*不能用="LiPing";*/student1.sex=’M’;student1.score=91.5;34計算機工程學院通過成員的引用,完成了對結構體變量student1的賦值。如果結構體成員又是一個結構體,需要利用若干個“.”,一級一級地找到最低層的成員,對其進行操作。例如:
student1.birthday.year=2003;結構體變量和其它變量一樣,可以在定義的時候給它賦初始值,即初始化。和前面四種形式對應它們的初始化情況如下:
第一種形式的初始化:35計算機工程學院structstudent{longnum;charname[20];charsex;floatscore;};structstudentstudent1={2003001,"LiPing",’M’,91.5};第二種形式的初始化:
structstudent{longnum;36計算機工程學院charname[20];
charsex;
floatscore;}student1={2003001,"LiPing",’M’,91.5};第三種形式的初始化:struct{longnum;
charname[20];
charsex;
floatscore;}student1={2003001,"LiPing",’M’,91.5};37計算機工程學院第四種形式的初始化:typedefstruct{longnum;
charname[20];
charsex;
floatscore;}STUD;STUDstudent1={2003001,"LiPing",’M’,91.5};
38計算機工程學院4.結構體數(shù)組在前面的學習中知道相同的數(shù)據(jù)類型可以存放在一個數(shù)組中,同樣多個屬于同一類型結構體的數(shù)據(jù)信息也可以存放在同一個數(shù)組中,構成結構體數(shù)組。例如,利用以前定義的結構體類型說明結構體數(shù)組:
structstudentstu[3];在本例中定義了一個數(shù)組stu,由3個struct
student類型的數(shù)組元素組成。對于結構體數(shù)組的初始化和以前的結構體及數(shù)組的初始化的方法類似,結構體數(shù)組初始化的基本形式為:39計算機工程學院定義的結構體數(shù)組={初值表列};例如:structstudentstu[3]={{2003001,"Liguohua",’M’,89.5},{2003002,"Zhangpiang",’F’,90},{2003003,"Liujun",’M’,87}};當對全部元素作初始化賦值時,也可不給出數(shù)組長度。40計算機工程學院
5.結構體指針在前面學習了不同用途的指針,如指向數(shù)組的指針、指向指針數(shù)組的指針和指向函數(shù)的指針等,對于結構體數(shù)據(jù)同樣也可以使用指針。把這種指向結構體的指針稱為結構體指針。結構體指針和前面學習的指針在特性上完全相象,指針變量也可以指向結構體數(shù)組。指針變量的值是結構體變量的起始地址。指向結構體變量的指針的一般形式: <結構體類型名>*<指針變量名>;(1)指向結構體變量的指針(2)指向結構體數(shù)組的指針(3)結構體指針作為函數(shù)參數(shù)
定義指向結構體變量的指針
typedefstructstudent{charname[20];intage;ints1,s2;}SD;
SDx,stu,*p;
p=&stu;成員的引用格式(1)結構體變量名.成員名stu.name例:scanf(“%s”,);scanf(“%d”,&x.age);x.s1=89;x.s2=78;gets(stu.name);(*p).age=21;scanf(“%d”,&p->s1);p->s2=90;(2)(*指針變量名).成員名(*p).age(3)指針變量名->成員名p->s1賦值語句p=&student;
指針變量p指向結構體變量student引用結構體中的成員變量:
(*p).成員名
或
p->成員名相當于student.成員名pstudent對結構體數(shù)組及其元素可以用指針來指向例如:
structstruct_name{charname[10];intnum;floatscore;};/*定義結構體類型標識符*/structstruct_namestd[30],*p;指向結構體數(shù)組的指針900390趙明879002王建899001李紅結構體數(shù)組stdstd[0]std[1]std[2]p賦值語句p=std;/*p指向一個結構體數(shù)組std*//*指針變量p存放的是數(shù)組std的首地址*/引用:p->name;p->num;p->score;趙明909003879002王建899001李紅結構體數(shù)組stdstd[0]std[1]std[2]思考:賦值語句p=std+1;和p++;
分別代表指針p指向哪里?p->name;p->num;p->score;代表的信息發(fā)生了什么變化?pp#include<stdio.h>structstudent{intnum;charname[20];charsex;intage;};/*指向結構體類型的數(shù)組的初始化*/structstudentstu[3]={{10101,"LiLin",'M',18},{10102,"ZhangFun",'M',19},{10104,"WangMin",'F',20}};voidmain(){structstudent*p;/*指向結構體類型的指針變量*/printf("NO\tName\t\t\tSex\tAge\n");for(p=stu;p<stu+3;p++)/*循環(huán)地址*/{printf("%5d\t%-20s%4c%8d\n",p->num,p->name,p->sex,p->age);//printf("%5d\t%-20s%4c%8d\n",(*p).num,(*p).name,(*p).sex,(*p).age);}}48計算機工程學院
6.動態(tài)空間管理*C語言為用戶提供了一些內(nèi)存管理函數(shù),這些內(nèi)存管理函數(shù)可以按需要動態(tài)地分配內(nèi)存空間,
也可把不再使用的空間回收待用,為有效地利用內(nèi)存資源提供了手段。常用的內(nèi)存管理函數(shù)有以下兩個:
(1)分配內(nèi)存空間函數(shù)malloc
函數(shù)原型:void*malloc(unsignedintsize);作用:在內(nèi)存的動態(tài)存儲區(qū)中分配一塊長度為size個字節(jié)的連續(xù)區(qū)域。函數(shù)的返回值為該區(qū)域的起始地址的指針。若分配不成功返回NULL。49計算機工程學院
調(diào)用形式:(<類型說明符>*)malloc(size)
<類型說明符>表示把該區(qū)域用于存放何種類型的數(shù)據(jù),(<類型說明符>*)表示把返回值強制轉換為該類型的指針。例如:#defineLENsizeof(structstudent)structstudent*p;p=(structstudent*)malloc(LEN);表示分配29個字節(jié)(structstudent類型的大?。┑膬?nèi)存空間,并把函數(shù)的返回值強制轉換為structstudent類型的指針后賦予指針變量p。50計算機工程學院(2)釋放內(nèi)存空間函數(shù)free函數(shù)原型:voidfree(void*block);作用:釋放block所指向的一塊內(nèi)存空間,block是一個任意類型的指針變量,它指向被釋放區(qū)域的首地址。被釋放區(qū)應是由malloc函數(shù)所分配的區(qū)域。調(diào)用形式:
free(p);
/*p是指向被釋放區(qū)域的指針*/注意使用這兩個函數(shù)需要引用兩個頭文件“stdio.h”和“alloc.h”。51計算機工程學院6.1.3技能訓練
【實驗6.1.1】有一個結構體變量student,包含學號和3門課的成績。要求編寫一個輸入函數(shù)進行賦值,并編寫一個輸出函數(shù)進行輸出操作。【指導】
(1)編程分析
●結構體中的3個成績可以定義成數(shù)組
●整個程序需要3個函數(shù):輸入函數(shù),輸出函數(shù),主函數(shù)
●注意函數(shù)的參數(shù)是結構體變量52計算機工程學院(2)示例程序#include“stdio.h”typedefstructstudent{intnum;floatscore[3];}STUDENT;STUDENTindata(){STUDENTstu;scanf(“%d”,&stu.num);scanf(“%f%f%f”,&stu.score[0],&stu.score[1],&stu.score[2]);return(stu);}53計算機工程學院voidprint(STUDENTstud){printf(“學號=%d\n”,stud.num);printf(“成績1=%f\n”,stud.score[0]);printf(“成績2=%f\n”,stud.score[1]);printf(“成績3=%f\n”,stud.score[2]);}voidmain(){STUDENTstud;printf(“請輸入學號和3門成績\n”);stud=indata();printf(“這個學生的信息是:\n”);”’print(stud);}54計算機工程學院(3)程序的執(zhí)行結果如圖6-4所示。圖6-4運行結果
在此例中使用了結構體函數(shù)和使用結構體變量在函數(shù)間傳遞數(shù)據(jù)。在主函數(shù)中說明了結構體55計算機工程學院變量stud并通過調(diào)用結構體函數(shù)indata()進行賦值,并將stud作為函數(shù)實參調(diào)用print()函數(shù)輸出數(shù)據(jù)?!緦嶒?.1.2】根據(jù)學生的學號查找學生的信息(要求利用函數(shù)實現(xiàn))?!局笇А浚?)編程分析
●先定義結構體數(shù)組,初始化n個學生的信息。
●輸入學生的學號,輸出查找到的結果在主函數(shù)中實現(xiàn)56計算機工程學院
●因此需定義查找函數(shù),函數(shù)的參數(shù)是學號和數(shù)組,函數(shù)的返回值是找到的學生信息的地址。(2)示例程序#include"stdio.h"structstudent{longnum;charname[20];charsex;floatscore;
};57計算機工程學院
structstudentstud[]={{2003101,"Wangling",’M’,94},{2003102,"Liping",’F’,87},{2003103,"Zhengjiujuan",’F’,93},{0,"\0",’\0’,0}};structstudent*find(structstudent*p,longnumber);voidmain(){structstudent*p;longnumber;charch;do{58計算機工程學院printf("\n請輸入學號:");scanf("%ld",&number);p=find(stud,number);if(p!=0){printf("學號姓名性別成績:\n");printf("%-10ld%-16s%c%8.1f\n",p->num,p->name,p->sex,p->score);}elseprintf(“沒有找到\n”);printf("\n請輸入'Y'or'y'繼續(xù)查找:");ch=getchar();59計算機工程學院}while(ch==’Y’||ch==’y’);}structstudent*find(structstudent*p,longnumber){while(p->num!=number&&p->num!=0) p++;if(p->num!=0)returnp;elsereturn0;}60計算機工程學院(3)程序的執(zhí)行結果如圖6-5所示。圖6-5運行結果61計算機工程學院在此程序中,利用結構體類型的指針p指向structstudent類型數(shù)組stud[]的首地址,在調(diào)用find()函數(shù)時,必須使用結構體數(shù)組stud[]的起始地址stud作為實參,傳給形參p,p指向stud(如圖所示)。在find函數(shù)中利用p對其進行操作,查找到后,返回p。
62計算機工程學院
【實驗6.1.3】計算學生的平均成績和不及格的人數(shù)?!局笇А?/p>
(1)編程分析●首先需定義學生類型的結構體,并定義結構體數(shù)組,保存學生的成績信息?!窦俣〝?shù)組的長度為N,則用for語句循環(huán)N次,累加出學生的總成績,最后除以N得到平均成績。●累加的同時判斷這個成績是否小于60,小則不及格人數(shù)加一。63計算機工程學院(2)偽代碼定義結構體structstudent定義結構體數(shù)組并初始化數(shù)據(jù)voidmain(){定義變量:用于保存循環(huán)控制變量,不及格人數(shù),總分,平均分循環(huán):{累加求和
if(成績<60)不及格人數(shù)++}輸出結果}64計算機工程學院(3)示例程序
#include<stdio.h>structstudent{longnum;charname[20];charsex;floatscore;}stu[5]={{2003101,"Liping",’M’,45},{2003102,"Zhangping",’M’,62.5},{2003103,"Hefang",’F’,92.5},{2003104,"Chengling",’F’,87},{2003105,"Wangming",’M’,58},};65計算機工程學院voidmain(){inti,c=0;floatave,sum=0;for(i=0;i<5;i++){sum+=stu[i].score;if(stu[i].score<60)c+=1;}ave=sum/5;printf("平均成績=%f\n不及格人數(shù)=%d\n",ave,c);}66計算機工程學院本例程序中定義了一個外部結構體數(shù)組stu,共5個元素,并作了初始化賦值。在main函數(shù)中用for語句逐個累加各元素的score,成員的和值存于sum之中,如score的值小于60(不及格)即計數(shù)器C加1,循環(huán)完畢后計算平均成績,并輸出平均分及不及格人數(shù)。(4)運行情況如下67計算機工程學院圖6-6運行結果68計算機工程學院6.1.4拓展與練習1.定義一個結構體類型,成員包括:姓名、電子信箱和QQ號碼。編寫input函數(shù)輸入5個成員的記錄,并編寫一個函數(shù)print打印輸出這些數(shù)據(jù).2.編寫程序,由鍵盤輸入某商場的各商品的商品名、價格、銷售量,計算各商品的銷售額,并輸出銷售額前10名的商品信息。3.a(chǎn)和b是按學號升序有序的結構體數(shù)組,結構體類型包括學號和成績兩個成員,把這兩個數(shù)組合并成一個按學號升序有序的數(shù)組c。69計算機工程學院6.1.5編程規(guī)范與常見錯誤1.不能將結構變量作為一個整體進行輸入和輸出。例如:
printf("Number=%ld\nName=%s\nSex=%c\nScore=%.2f\n",student);是錯誤的,應該是:printf("Number=%ld\nName=%s\nSex=%c\nScore=%.2f\n",student.number,,student.sex,student.score);70計算機工程學院2.成員可以是任意類型,如果成員本身又屬于一個結構體類型,要一級一級地找到最低一級的成員如:student結構體變量s1,訪問學生的生日:s1.birthday.month,不能使用s1.birthday,因為birthday本身是一個結構體。結構體是一個類型,而不是變量,定義變量時關鍵字struct不能省略,如定義一個學生:structstudents1,通常用typedefstructstudentSTU,這時可以用STU來定義變量,如STUs1;71計算機工程學院任務2共用體學習目標
掌握共用體類型的說明、共用體變量的定義及初始化方法、掌握共用體變量成員的引用。72計算機工程學院6.2.1案例講解1.問題描述:有一個unsignedlong型整數(shù),分別將前2個字節(jié)和后2個字節(jié)作為兩個unsignedshort型輸出。2.編程分析
unsignedlong類型占用4個字節(jié),取其中的兩個字節(jié)需要定義unsignedshort型變量。
方法一:定義unsignedshort型指針p,則*p和*(p+1)是前2個字節(jié)和后2個字節(jié)。
方法二:定義兩個unsignedshort變量,并與unsignedlong變量使用同一個地址空間,即定義共用體。73計算機工程學院3.編寫源程序
#include<stdio.h>uniondata{unsignedlongul;unsignedshortua[2];};voidmain(){uniondataw;unsignedshorthighbyte,lowbyte;w.ul=0x12345678;highbyte=w.ua[1];lowbyte=w.ua[0];printf("整型變量的值是%lx\n",w.ul);printf("前兩個字節(jié)是%x,后兩個字節(jié)是%x\n",highbyte,lowbyte);}74計算機工程學院4.程序運行結果圖6-7運行結果75計算機工程學院5.歸納分析
(1)程序中&u1和ua是相等的,u1和ua共用同一塊存儲空間,即sizeof(w)=4。(2)公用體與結構體的使用形式類似,但含義不同,如果把w定義成structdata,則sizeof(w)=4+2+2=8,它可以存儲一個長整型數(shù)據(jù)“和”兩個整型數(shù)據(jù),現(xiàn)在w是uniondata,它可以存儲一個長整型數(shù)據(jù)“或”兩個整型數(shù)據(jù),兩者選一,因為它們共用一個存儲空間。(3)printf語句中%lx是以16進制輸出長整型。可以看到長整型中的高16位0x1234放在高的地址空間了,低16位放在低的地址空間里。76計算機工程學院6.2.2基礎理論1.共用體類型的定義
有時需要使不同的數(shù)據(jù)使用共同的存儲區(qū)域,在C語言中利用共用體類型(又稱聯(lián)合體)來實現(xiàn)。共用體也是一種構造數(shù)據(jù)類型,它的類型定義、變量說明和引用在形式上類似于結構體,二者本質區(qū)別是存儲方式的不同。共用體的定義的一般形式:
union〈共用體名〉{
〈成員列表〉}變量列表;77計算機工程學院
例如,定義把一個整型變量、一個字符型變量、一個實型變量放在同一個地址開始的內(nèi)存單元中。圖6-8共用體存儲示意圖
整型變量i
字符變量ch
實型變量f78計算機工程學院
uniondata{inti;
charch;
floatf;};設內(nèi)存單元地址為1200,則它們的分配示意如圖6-8,三者需要的內(nèi)存空間不一樣,但都從1200單元開始分配,分配多大的空間呢?如果上例使用的是結構則內(nèi)存為結構體分配:2+1+4=7字節(jié)的空間,但在共用體中因為每次只使用共用體中的一個變量,所以分配的空間長度是最長成員的長度,在本例中是4個字節(jié),這就是共用體和結構體的本質區(qū)別。79計算機工程學院2.共用體變量的說明和引用和結構體的說明對應,共用體的變量說明有四種方式:
(1)union〈共用體名〉{〈成員列表〉}變量列表;例如:uniondata{inti;
charch;
floatf;}a,b,c;說明了三個共用體變量a、b和c。80計算機工程學院(2)union〈共用體名〉{〈成員列表〉};
union共用體名變量列表;例如:uniondata{inti;
charch;
floatf;};
uniondataa,b,c;81計算機工程學院(3)union
{〈成員列表〉}變量列表;(4)typedefunion
{〈成員列表〉}共用體類型名;
共用體類型名變量列表;82計算機工程學院例如:typedefunion{inti;charch;
floatf;}DATA;
DATAa,b,c;共用體變量的引用和結構體、數(shù)組一樣,只能引用共用體變量的成員。例如前面定義的三個共用體變量a,b,c,可以這樣引用:83計算機工程學院
a.i;/*引用共用體變量中的整型變量i*/
a.ch;/*引用共用體變量中的字符變量ch*/
a.f;/*引用共用體變量中的實型變量f*/共用體類型數(shù)據(jù)有如下的特點:
(1)共用體的內(nèi)存段可以存放幾種類型的數(shù)據(jù),但一次只能存放一個類型成員,且共用體變量中的值是最后一次存放的成員的值,如:
a.i=1;
a.ch=‘a(chǎn)’;
a.f=1.5;84計算機工程學院
完成以上三個賦值語句后,共用體變量的值是1.5,而a.i=1和a.ch=′a′已無意義。(2)共用體變量不能初始化,例如:
uniondata
{inti;
charch;
floatf;
}
a={1,’a’,1.5};(3)可以使用共用體指針,同樣可以用指針形式來使用共用體成員。例如:
85計算機工程學院定義指針變量p:
DATA*p;p=&a;
則可以用下面的方式使用共用體的成員:
p->i=1;
p->ch=‘a(chǎn)’;
p->f=1.5;C語言最初引入共用體的目的之一是為了節(jié)省內(nèi)存空間,另一個目的是可以將一種類型的數(shù)據(jù)轉換為另一種類型的數(shù)據(jù)使用。86計算機工程學院
6.2.3技能訓練
【實驗6.2.1】設有若干個人員的數(shù)據(jù),其中有學生和教師。學生的數(shù)據(jù)包括:姓名,學碼,性別,專業(yè),班級。教師的數(shù)據(jù)包括:姓名,工號,性別,職業(yè),職務??梢钥闯?,學生和教師所包含的數(shù)據(jù)是不同的,現(xiàn)要求把他們放在同一表格中,見表6-1。如果“job”項為“s”(學生),則第五項為class(班級)。如果“job”項為“t”(教師),則第五項為position(職務)。87計算機工程學院表6-1人員結構表【指導】
(1)編程分析
●定義一個結構體解決此問題,不同的部分(class和position)可以定義成共用體,即一88計算機工程學院個結構體類型中包含一個共用體成員。
●程序中當job的值是‘s’時,使用共用體中的class成員,當job的值是‘t’時,使用position成員。(2)示例程序
struct{intnum;charname[10];charsex;89計算機工程學院charjob;union{intclass;charposition[10];}category;}person[2];voidmain(){intn,i;for(i=0;i<2;i++){90計算機工程學院scanf(“%d%s%c%c”,&person[i].num,person[i].name,&person[i].sex,&person[i].job);if(person[i].job==’s’)scanf(“%d”,&person[i].category.class);elseif(person[i].job==’t’)scanf(“%s”,person[i].category.position);elseprintf(“inputerror!”);printf(“\n”);printf(“No.Namesexjobclass/position\n”);for(i=0;i<2;i++){91計算機工程學院if(person[i].job==’s’)printf(“%-6d%-10s%-3c%-3c%-6d\n”,person[i].num,person[i].name,person[i].sex,person[i].job,person[i].category.class);elseprintf(“%-6d%-10s%-3c%-3c%-6s\n”,person[i].num,person[i].name,person[i].sex,person[i].job,person[i].category.position);}}}92計算機工程學院6.2.4拓展與練習
1.有以下定義和語句,則sizeof(a)的值是【】,而sizeof(a.share)的值是【】
structdate{intday;intmonth;intyear;union{intshare1floatshare2;}share;}a;93計算機工程學院2.整型在內(nèi)存中占4個字節(jié),請編寫一個程序,將四個字符(char)拼成一個長整型(long)數(shù)據(jù)。編寫一個函數(shù)將四個字節(jié)的內(nèi)容作為一個long型數(shù)據(jù)輸出。94計算機工程學院
6.2.5編程規(guī)范與常見錯誤
1.理解共用體的含義,某一時刻只有一個成員的數(shù)據(jù)是有效的。例如定義共用體:uniondata{inti;charch;
floatf;}a;那么執(zhí)行語句a.i=500;a.ch=’a’;printf(“%d”,a.i);結果不是500。95計算機工程學院2.注意結構體與共用體的區(qū)別,假如有如下定義:
那么sizeof(a)=max(sizeof(i),sizeof(ch),sizeof(f))=4;sizeof(b)=sizeof(i)+sizeof(ch)+sizeof(f)=2+1+4=7;因為a中某一時刻只有一個數(shù)據(jù)所以4個字節(jié)足夠了,而b中3個成員都占用空間,需要7個字節(jié)。uniondata{inti;charch;floatf;}a;structdata{inti;charch;floatf;}b;96計算機工程學院任務3枚舉學習目標
領會枚舉類型的作用,枚舉類型變量的定義、使用。97計算機工程學院
6.3.1案例講解
1.問題描述:一個口袋里有紅、黃、藍、白、黑五種顏色的球若干個,依次從口袋中取出三個球,問:三個球的顏色正好都不相同的情況有幾種?輸出所有可能的排列組合。2.編程分析設取出的球為i,j,k,根據(jù)題意i,j,k分別為5種顏色之一,并且i≠j≠k,可以用窮舉法,一一測試,看哪組符合條件,就輸出它。98計算機工程學院偽代碼如下:定義五種顏色;voidmain(){定義顏色變量i,j,k;定義整數(shù)變量n累計總的次數(shù);外循環(huán):第一個球i從red到black中循環(huán):第二個球j從red到black如果i與j顏色相同則不取當i與j不相同,進入內(nèi)循環(huán):99計算機工程學院第三個球k也有五種可能當k與i不同并且與j也不同時
{輸出次數(shù)n;輸出三個球的顏色;輸出換行;
}最后輸出方案總數(shù)n;}100計算機工程學院3.編寫源程序#include<stdio.h>enumcolor{red,yellow,blue,white,black};voidprintcolor(enumcolork);voidmain(){enumcolori,j,k;intn;n=0;for(i=red;i<=black;i++)for(j=red;j<=black;j++)if(i!=j){101計算機工程學院for(k=red,k<=black;k++)if((k!=i)&&(k!=j)){n++;printf(“%-4d”,n);printcolor(i);printcolor(j);printcolor(k);printf(“\n”);}}102計算機工程學院printf(“\ntotal:%5d\n”,n);}voidprintcolor(enumcolork){switch(k){casered:printf(%-10s”,”red”);break;caseyellow:printf(“%-10s”,”yellow”);break;caseblue:printf(“%-10s”,”blue”);break;casewhite:printf("%-10s","white");break;caseblack:printf("%-10s","black");break;default:break;}}103計算機工程學院4.程序運行結果圖6-9運行結果104計算機工程學院5.歸納分析
(1)因為顏色一共有五種,可以一一例舉出來,可以定義成枚舉類型(2)枚舉常量與整數(shù)有對應關系,red是0,yellow是1,依此類推。因此i,j,k可以循環(huán)的加一,也可以比較大小。(3)如果直接輸出i,j,k則只能輸出對應的整數(shù),如printf("%d",red)結果是0,因此用函數(shù)printcolor處理一下,i=red則輸出printf("%-10s","red")。105計算機工程學院
6.3.2基礎理論
如果一個變量只有幾種可能的值,可以將所有的值列舉出來,在C語言將這種結構定義為枚舉類型。“枚舉”就是將變量可能的值一一列舉出來的含義。變量的值只能取列舉出來的值之一。1.枚舉類型的定義枚舉類型定義的一般形式為:
enum〈枚舉類型名〉{枚舉值表};例如:enumweek{SUN,MON,TUES,WED,THUR,FRI,SAT};定義了一個week是枚舉類型名,有7個數(shù)據(jù)(稱為“枚舉元素”或“枚舉常量),但它的值106計算機工程學院是SUN到SAT之一,并不是7個值,列出的7個數(shù)據(jù)是它的取值范圍。2.枚舉變量的說明與使用枚舉變量也可用不同的方式說明,即先定義后說明,同時定義說明或直接說明。枚舉變量說明的三種方法:
(1)先定義枚舉類型,然后說明枚舉變量。例:enumcolour{red,green,blue,yellow,white};enumcolourchange,select;107計算機工程學院
(2)在定義枚舉類型的同時,說明枚舉變量。例:enumcolour{red,green,blue,yellow,white}change,select;
(3)直接定義枚舉變量。例:enum{red,green,blue,yellow,white}change,select;說明:108計算機工程學院●枚舉元素是常量。在C編譯器中,按定義的順序取值0、1、2、...。例change=green;
printf("%d",change);
輸出整數(shù)1。●枚舉元素是常量,不是變量,因此不能賦值。
red=0;colour=1;
但在定義枚舉類型時,可以指定枚舉常量的值,如:
enumcolour{red=1,green=2,blue,yellow,white};
109計算機工程學院
此時,red,green,blue,...的值從red的值順序加1。如:yellow=4。
●枚舉值可以作判斷比較的條件,例如:
if(change==red)....
if(select>green)....
●整型與枚舉類型是不同的數(shù)據(jù)類型,不能直接賦值,如:
enumweek{sun=7,mon=1,tue,wed,thu,fri,sat}workday;workday=1但可以通過強制類型轉換賦值,如:workday=(enumweek)2;110計算機工程學院6.3.3技能訓練
【實驗6.3.1】設某月的第一天是Sunday,請給出其它的日期是星期幾?!局笇А浚?)編程分析用標識符sun,mon,…,sat表示星期,這比用數(shù)字1,2,…,7來表示要清晰,所以使用枚舉可以提高程序的可讀性。定義枚舉類型表示星期(week),假定一個月是30天,定義數(shù)組(weekday)保存每一天是星期幾,數(shù)組的長度是31,0號元素不用,數(shù)組的類型是week,那么:weekday[1]=sunday,表示1號是星期天。111計算機工程學院枚舉型與整型有對應關系,sunday+1就是monday,當?shù)搅酥苣﹕atday(對應整數(shù)6),下一天就應該是sunday(對應整數(shù)0)。(2)示例程序
voidmain(){enumweek{sun,mon,tue,wed,thu,fri,sat}weekday[31],j;inti;j=sun;for(i=1;i<=30;i++)112計算機工程學院{weekday[i]=j;
j++;
if(j>sat)
j=sun;}for(i=1;i<=30;i++){
switch(weekday[i])
{
casesun:printf("%3dSunday",i);break;
casemon:printf("%3dMonday",i);break;
casetue:printf("%3dTuesday",i);break;
casewed:printf("%3dWednesday",i);break;
casethu:printf("%3dThursday",i);break;
casefri:printf("%3dFriday",i);break;
casesat:printf("%3dSaturday\n",i);break;}
}printf("\n");
}113計算機工程學院6.3.4拓展與練習1.假設有如下定義:enumdata{MIN,first=15,last=20,total,num=50,max=1000}請指出各個枚舉常量的值2.以下對枚舉類型名的定義中正確的是enuma={one,two,three
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- FPGA基因測序加速-洞察及研究
- 社工角色與職業(yè)發(fā)展-洞察闡釋
- 網(wǎng)絡切片安全隱私保護機制-洞察闡釋
- 食品感官特性與營養(yǎng)成分的調(diào)控-洞察闡釋
- 北京海淀2025屆化學高二下期末統(tǒng)考試題含解析
- 江西省八所重點中學2025屆高二下化學期末預測試題含解析
- 2025屆河北省承德市第二職業(yè)中學高二化學第二學期期末學業(yè)水平測試模擬試題含解析
- 食品安全與質量控制新技術-洞察闡釋
- 山西省太原市育英中學2025屆化學高二下期末質量跟蹤監(jiān)視模擬試題含解析
- 健康監(jiān)測設備智能化與AI系統(tǒng)融合研究
- 江蘇省環(huán)保集團有限公司招聘筆試題庫2024
- 鐵路貨車轉向架檢修新技術
- 電鍍環(huán)評評估投標方案技術標
- 山東省濟南市市中區(qū)2023-2024學年八年級下學期期末數(shù)學試題
- 光伏土地征地合同
- 竹類樹種識別與應用-剛竹類
- 五年級上冊閱讀理解題20套(帶答案)
- 《蘇幕遮》(周邦彥)公開課一等獎
- 《兩辦意見》解析培訓課件-2024年
- 糖尿病中醫(yī)科普知識講座總結
- 農(nóng)資銷售半年工作總結報告
評論
0/150
提交評論