




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
實(shí)用小型通訊錄管理能力目標(biāo)知識(shí)目標(biāo)能理解三種編譯預(yù)處理的概念:宏定義、文件包含、條件編譯;能掌握自定義數(shù)據(jù)類型的定義和使用方法,包括枚舉類型變量、共用類型變量、結(jié)構(gòu)類型變量的定義與使用;會(huì)用結(jié)構(gòu)體類型變量的指針動(dòng)態(tài)建立鏈表,并能夠?qū)︽湵磉M(jìn)行插入、刪除等操作。能掌握數(shù)據(jù)文件的多種讀寫方式,并能熟練應(yīng)用于程序設(shè)計(jì)中。掌握C預(yù)處理命令掌握C程序中多文件運(yùn)行方法掌握C結(jié)構(gòu)體、共用體和枚舉類型及其應(yīng)用掌握C程序?qū)ξ募淖x寫應(yīng)用
任務(wù)1結(jié)構(gòu)體的設(shè)計(jì)與訪問(wèn)任務(wù)2數(shù)據(jù)文件的存取項(xiàng)目分解任務(wù)1結(jié)構(gòu)體的設(shè)計(jì)與訪問(wèn)#include<stdio.h>#include<stdlib.h>#include<string.h>typedefstructaddress{charname[18];chartel[20];structaddress*next;}ADDR;4.1.1問(wèn)題情景及其實(shí)現(xiàn)
編寫設(shè)計(jì)通訊錄成員信息結(jié)構(gòu)體,并錄入成員信息,然后再顯示輸出。
輸入人員姓名:張三↙輸入人員電話姓名電話張/p>
程序運(yùn)行結(jié)果:intmain(){ADDR*h;h=(ADDR*)malloc(sizeof(ADDR));printf(“輸入人員姓名:”);scanf(“%s”,h->name);printf(“輸入人員電話:”);scanf(“%s”,h->tel);h->next=NULL;printf(“姓名\t電話\n”);printf(“%s\t%s\n”,h->name,h->tel);return0;}編譯預(yù)處理結(jié)構(gòu)體共用體枚舉類型類型定義符4.1.2知識(shí)分解一、預(yù)處理
編譯預(yù)處理是指,在對(duì)源程序進(jìn)行編譯之前,先對(duì)源程序中的編譯預(yù)處理命令進(jìn)行處理;然后再將處理的結(jié)果,和源程序一起進(jìn)行編譯,以得到目標(biāo)代碼。一、預(yù)處理1、宏定義(1)不帶參數(shù)的宏定義
指程序代碼中用一個(gè)叫做宏名的指定標(biāo)識(shí)符來(lái)代表一個(gè)字符串,前面我們介紹過(guò)的符號(hào)常量的定義方式就屬于不帶參數(shù)的宏定義。不帶參數(shù)宏定義的一般格式為:
#define宏名字符串【例4-1】在程序中定義宏名代替數(shù)組長(zhǎng)度。#defineARRAY_SIZE5#include<stdio.h>intmain(){intarray[ARRAY_SIZE];inti,sum=0;for(i=0;i<ARRAY_SIZE;i++){array[i]=i;sum+=array[i];}for(i=0;i<ARRAY_SIZE;i++){printf("array[%d]=%d\n",i,array[i]);}printf("sum=%d\n",sum);return0;}程序運(yùn)行結(jié)果如下:array[0]=0array[1]=1array[2]=2array[3]=3array[4]=4sum=10說(shuō)明:本例中使用宏名ARRAY_SIZE代表數(shù)組長(zhǎng)度,當(dāng)需要改變數(shù)組長(zhǎng)度(元素個(gè)數(shù))時(shí),只需修改#define命令行即可,一改全改,提高了程序的通用性?!纠?-2】輸入半徑,輸出給定半徑的圓周長(zhǎng)、圓面積和球體面積。要求在程序中使用宏名代替圓周率、圓周長(zhǎng)、圓面積和球體面積。#definePI3.14159#defineL2.0*PI*r#defineSPI*r*r#defineV4.0*S*r/3#include<stdio.h>intmain(){floatr,len,s;printf("inputr:");scanf("%f",&r);len=2.0*PI*r;printf("L=%.4f,S=%.4f,V=%.4f\n",L,S,V);return0;}程序運(yùn)行結(jié)果如下:inputr:8↙L=50.2654,S=201.0618,V=2144.6588printf("L=%.4f,S=%.4f,V=%.4f\n",2.0*3.14159*r,3.14159*r*r,4.0*3.14159*r*r/3);使用不帶參數(shù)宏定義應(yīng)注意的問(wèn)題
A、為了增加程序的可讀性,建議宏名使用大寫字母,這樣可以明顯的與變量名區(qū)分開(kāi)來(lái),而其他的標(biāo)識(shí)符使用小寫字母。B、使用字符串替換宏名時(shí),編譯系統(tǒng)僅僅做簡(jiǎn)單原樣替換而不做語(yǔ)法檢查,即使字符串存在書寫錯(cuò)誤也照樣原樣替換C、在不帶參宏定義作用域內(nèi)的程序代碼中出現(xiàn)用雙引號(hào)括起來(lái)且與宏名相同的字符串時(shí),將不進(jìn)行替換。D、宏定義的作用域是從定義處開(kāi)始到源文件結(jié)束,但根據(jù)需要可用undef命令終止其作用域。undef命令的一般形式為:#undef宏名【例4-3】在程序中定義宏名代替printf語(yǔ)句中的格式字符串。#defineFORM1"%d\n"#defineFORM2"%d\t%d\n"#defineFORM3"%d\t%d\t%d\n"#include<stdio.h>intmain(){inta=1,b=2,c=3;printf(FORM1,a);printf(FORM1,b);printf(FORM1,c);printf(FORM2,a,b);printf(FORM1,c);printf(FORM3,a,b,c);return0;}123123123程序運(yùn)行結(jié)果如下:
在本例中使用不帶參數(shù)的宏定義,通過(guò)定義宏名來(lái)代表printf語(yǔ)句中的格式字符串,控制3個(gè)整型變量a,b,c的輸出方式,具體實(shí)現(xiàn)的輸出效果請(qǐng)自行分析。一、預(yù)處理1、宏定義(2)
帶參數(shù)的宏定義
與不帶參數(shù)的宏定義不同的是,帶參數(shù)的宏定義不僅僅要進(jìn)行簡(jiǎn)單的字符串替換,還要進(jìn)行參數(shù)替換。帶參數(shù)宏定義的一般格式為:
#define宏名(形參表)字符串例如:#defineAREA(length,width)((length)*(width))s=AREA(10,5);s=((10)*(5))宏展開(kāi)注意:帶參數(shù)宏定義中宏名與圓括號(hào)之間不能有空格,否則將空格后的所有字符作為字符串以不帶參數(shù)的宏定義方式處理?!纠?-4】輸入兩個(gè)整數(shù),求出兩個(gè)整數(shù)相除的余數(shù)。要求使用帶參的宏定義實(shí)現(xiàn)。#defineMOD(x,y)((x)%(y))#include<stdio.h>voidmain(){inta,b;printf("\n請(qǐng)輸入a和b兩個(gè)整數(shù):");scanf("%d,%d",&a,&b);printf("a%%b=%d\n",MOD(a,b));}printf("a%%b=%d\n",((a)%(b)));注意:需要注意的是在使用帶參的宏定義時(shí),如果宏名后圓括號(hào)中的實(shí)參使用表達(dá)式形式,字符串本身和字符串中的形參最好都使用圓括號(hào)括起來(lái),否則容易出現(xiàn)錯(cuò)誤。#defineMOD(x,y)(x%y)#include<stdio.h>intmain(){inta,b;scanf("%d,%d",&x,&y);
printf("a%%b=%d\n",MOD(a+1,b+1));return0;}請(qǐng)輸入a和b兩個(gè)整數(shù):12,5↙a%b=2程序運(yùn)行結(jié)果如下:printf("a%%b=%d\n",(a+1%b+1));【例4-5】輸入兩個(gè)整數(shù),輸出其中較大的那個(gè)整數(shù)。要求分別定義函數(shù)和帶參數(shù)的宏定義實(shí)現(xiàn)。#include<stdio.h>intmax(intx,inty)
;ingmain(){inta,b;printf("\n請(qǐng)輸入a和b兩個(gè)整數(shù):");
scanf("%d,%d",&a,&b);printf("max=%d\n",max(a+2,b+2));return0;}intmax(intx,inty){return(x>y?x:y);}#defineMAX(x,y)((x)>(y)?(x):(y))#include<stdio.h>intmain(){inta,b;printf(“\n請(qǐng)輸入a和b兩個(gè)整數(shù):”);scanf(“%d,%d”,&a,&b);printf(“\nmax=%d”,MAX(a+2,b+2));return0;}用函數(shù)實(shí)現(xiàn)用帶參的宏定義實(shí)現(xiàn)
需要注意的是帶參宏定義中的參數(shù)無(wú)數(shù)據(jù)類型的概念,宏展開(kāi)時(shí)不分配內(nèi)存存儲(chǔ)單元,不會(huì)進(jìn)行值傳遞,也沒(méi)有類似函數(shù)返回值的概念。
所謂文件包含是指將指定的某個(gè)源文件的內(nèi)容(代碼)全部包含到當(dāng)前源文件中,執(zhí)行文件包含命令的效果實(shí)際上是將兩個(gè)或多個(gè)源文件合并成了一個(gè)源文件。文件包含功能使用include命令實(shí)現(xiàn)。(1)文件包含命令的一般格式有兩種形式:格式1:#include<文件名>
格式2:#include"文件名"一、預(yù)處理2、文件包含(2)文件包含的功能①文件包含的功能是在編譯預(yù)處理時(shí),將include命令后指定文件的內(nèi)容替換該命令行。合理使用“文件包含”命令可以有效減少程序開(kāi)發(fā)人員的重復(fù)勞動(dòng)量,提高編碼效率;同時(shí)也為多人協(xié)同開(kāi)發(fā)一個(gè)大型C程序提供了方便。例如:一組程序開(kāi)發(fā)人員開(kāi)發(fā)某一程序時(shí)都需要頻繁使用一組固定的符號(hào)常量,這時(shí)可以將這些符號(hào)常量的宏定義命令單獨(dú)寫在一個(gè)頭文件中,然后各個(gè)開(kāi)發(fā)人員可以使用include命令將該頭文件包含到自己所寫的源文件中,而不用每個(gè)人都去重復(fù)定義這些符號(hào)常量。②調(diào)用系統(tǒng)函數(shù)前使用文件包含命令將該系統(tǒng)函數(shù)的頭文件包含到本源文件中。前面三個(gè)項(xiàng)目的程序中,如果需要使用標(biāo)準(zhǔn)庫(kù)函數(shù)中的數(shù)學(xué)函數(shù)(如abs函數(shù))時(shí),要在程序開(kāi)頭處使用文件包含命令#include<math.h>包含數(shù)學(xué)庫(kù)函數(shù)的頭文件。在編譯預(yù)處理階段,將會(huì)用數(shù)學(xué)函數(shù)庫(kù)的頭文件內(nèi)容替換#include<math.h>命令行。一、預(yù)處理2、文件包含(3)使用include命令時(shí)的注意事項(xiàng)①一條include命令只能包含一個(gè)指定的源文件,如果要包含多個(gè)源文件,需要使用多條include命令。②使用多條文件包含命令時(shí),應(yīng)該注意文件包含命令的書寫順序。③文件包含允許嵌套,即一個(gè)被包含的文件中又可以包含另一個(gè)文件。一、預(yù)處理2、文件包含(1)條件編譯命令的幾種格式格式1:#ifdef標(biāo)識(shí)符程序段1#else
程序段2#endif一、預(yù)處理3、條件編譯
這種格式的功能是:如果標(biāo)識(shí)符已經(jīng)被定義過(guò)(一般使用#define命令定義),則對(duì)程序段1進(jìn)行編譯;否則對(duì)程序段2進(jìn)行編譯,格式中的#else部分可以省略。格式2:#ifndef標(biāo)識(shí)符程序段1#else
程序段2#endif(1)條件編譯命令的幾種格式一、預(yù)處理3、條件編譯
這種格式的功能是:如果標(biāo)識(shí)符沒(méi)有被定義過(guò),則對(duì)程序段1進(jìn)行編譯;否則對(duì)程序段2進(jìn)行編譯,格式中的#else部分同樣可以省略。格式3:#if(表達(dá)式)
程序段1#else
程序段2#endif(1)條件編譯命令的幾種格式一、預(yù)處理3、條件編譯
這種格式的功能是:如果表達(dá)式成立,即表達(dá)式的值為真(非0),則對(duì)程序段1進(jìn)行編譯;否則對(duì)程序段2進(jìn)行編譯,格式中的#else部分可以省略?!纠?-6】輸入一個(gè)字符串,可以任選兩種形式輸出,一為原樣輸出;一為加密輸出,即將字符串中每一字母變?yōu)樽帜副碇械南乱蛔帜篙敵?。要求使用條件編譯來(lái)控制輸出形式。#include<stdio.h>#definemax80#definePASSWORD1intmain(){charstr[max];inti;printf("\n請(qǐng)輸入一行字符:");gets(str);
#if(PASSWORD){for(i=0;i<max;i++){if(str[i]!='\0')if(str[i]>='a'&&str[i]<'z'||str[i]>='A'&&str[i]<'Z')str[i]+=1;elseif(str[i]=='z'||str[i]=='Z')str[i]-=25;}}
#endifprintf("
\n輸出的這行字符為:\n%s",str);return0;}
結(jié)構(gòu)化程序設(shè)計(jì)思想要求編寫大型程序時(shí)采用自頂向下逐步細(xì)化和模塊化的方法。將大型程序按功能分解為若干較大的模塊,再將大模塊按同樣的原則分解為若干小模塊,直到分解出的模塊可以直接編寫一個(gè)或多個(gè)函數(shù)實(shí)現(xiàn)為止。這樣,大型程序可由多人共同開(kāi)發(fā)完成,每個(gè)人負(fù)責(zé)編寫一個(gè)或多個(gè)模塊。我們以一個(gè)簡(jiǎn)單事例來(lái)說(shuō)明。一、預(yù)處理4、多文件程序的調(diào)試方法【例4-7】如果一個(gè)C程序有如下內(nèi)容的3個(gè)源文件file1.c、fie2.c和file3.c,分別使用工程文件和文件包含命令兩種方法將3個(gè)源文件編譯并連接成一個(gè)可執(zhí)行文件。#include<stdio.h>intmain(){intx,y,m,n;printf("請(qǐng)輸入x和y兩個(gè)整數(shù):");scanf("%d,%d",&x,&y);m=fun1(x,y);n=fun2(x,y);printf("\n%d*%d=%d",x,y,m);printf("\n%d^%d=%d",x,y,n);return0;}file1.c:intfun1(inta,intb){intc;c=a*b;returnc;}intfun2(inta,intb){inti,p=1;for(i=1;i<=b;i++)p*=a;returnp;}file2.c:file3.c:兩種方法:1、使用工程文件,將3個(gè)源文件包含在同一工程之下,可以統(tǒng)一進(jìn)行編譯。只是需要在file1.c文件中擴(kuò)展file2.c和file3.c文件中函數(shù)fun1和fun2的作用域;intfun1(inta,intb);intfun2(inta,intb);【例4-7】如果一個(gè)C程序有如下內(nèi)容的3個(gè)源文件file1.c、fie2.c和file3.c,分別使用工程文件和文件包含命令兩種方法將3個(gè)源文件編譯并連接成一個(gè)可執(zhí)行文件。#include<stdio.h>intmain(){intx,y,m,n;printf("請(qǐng)輸入x和y兩個(gè)整數(shù):");scanf("%d,%d",&x,&y);m=fun1(x,y);n=fun2(x,y);printf("\n%d*%d=%d",x,y,m);printf("\n%d^%d=%d",x,y,n);return0;}file1.c:intfun1(inta,intb){intc;c=a*b;returnc;}intfun2(inta,intb){inti,p=1;for(i=1;i<=b;i++)p*=a;returnp;}file2.c:file3.c:兩種方法:2、使用文件包含命令,此時(shí)文件file2.c和file3.c不與file1在同一工程之下,需要使用include命令將其包含到當(dāng)前工程的源文件中;intfun1(inta,intb);intfun2(inta,intb);#include"file3.c"#include"file2.c"二、結(jié)構(gòu)體
在實(shí)際問(wèn)題中,一組數(shù)據(jù)往往具有不同的數(shù)據(jù)類型。例如,在學(xué)生登記表中,姓名應(yīng)為字符串型;學(xué)號(hào)可為整型或字符串型;年齡應(yīng)為整型;性別應(yīng)為字符串型;成績(jī)可為整型或?qū)嵭?。顯然不能用一個(gè)數(shù)組來(lái)存放這一組數(shù)據(jù)。因?yàn)閿?shù)組中各元素的類型都必須一致,以便于編譯系統(tǒng)處理。結(jié)構(gòu)與數(shù)組不同,是不同數(shù)據(jù)類型的集合。結(jié)構(gòu)中的不同類型的數(shù)據(jù)都是有關(guān)聯(lián)的,它們被作為一個(gè)整體來(lái)看待。如同在調(diào)用函數(shù)之前要先定義函數(shù)一樣,結(jié)構(gòu)作為一種自定義的數(shù)據(jù)類型,在使用它之前也必須先定義。二、結(jié)構(gòu)體1、結(jié)構(gòu)體的定義struct結(jié)構(gòu)名{數(shù)據(jù)類型標(biāo)識(shí)符1變量名1;數(shù)據(jù)類型標(biāo)識(shí)符2變量名2;
…………數(shù)據(jù)類型標(biāo)識(shí)符n變量名n;};結(jié)構(gòu)類型定義的一般形式是:structChild{
doubleheight;
doubleweight;
intyears;
intmonths;
chargender;
};
例如:::
定義了一個(gè)結(jié)構(gòu)類型Child,struct是關(guān)鍵字。Child類型包含兩個(gè)double、兩個(gè)int和一個(gè)char成員,它可以與C的基本數(shù)據(jù)類型一樣地使用。(注意)結(jié)構(gòu)類型定義也是一個(gè)語(yǔ)句,所以結(jié)尾必須有分號(hào)(;),否則,會(huì)產(chǎn)生編譯錯(cuò)誤。二、結(jié)構(gòu)體2、結(jié)構(gòu)體變量的定義
有了結(jié)構(gòu)類型的定義之后,就可以定義這種類型的變量,結(jié)構(gòu)類型的變量在內(nèi)存中占的字節(jié)數(shù)是其各個(gè)成員在內(nèi)存中占的字節(jié)數(shù)的總和。要定義一個(gè)結(jié)構(gòu)類型的變量,可以采用以下三種方法。
(1)先定義結(jié)構(gòu)類型,再定義結(jié)構(gòu)類型變量。structexample{inta;floatb;doublec;example*ptr;};這種方式定義結(jié)構(gòu)變量的一般形式是:結(jié)構(gòu)類型名變量名1,變量名2,…,變量名n;structexamplex,y;二、結(jié)構(gòu)體2、結(jié)構(gòu)體變量的定義
有了結(jié)構(gòu)類型的定義之后,就可以定義這種類型的變量,結(jié)構(gòu)類型的變量在內(nèi)存中占的字節(jié)數(shù)是其各個(gè)成員在內(nèi)存中占的字節(jié)數(shù)的總和。要定義一個(gè)結(jié)構(gòu)類型的變量,可以采用以下三種方法。
(2)在定義結(jié)構(gòu)類型的同時(shí)定義結(jié)構(gòu)變量。structexample{inta;floatb;doublec;example*ptr;}x,y;這種方式定義結(jié)構(gòu)變量的一般形式是:struct結(jié)構(gòu)名{成員列表}變量名列表;二、結(jié)構(gòu)體2、結(jié)構(gòu)體變量的定義
有了結(jié)構(gòu)類型的定義之后,就可以定義這種類型的變量,結(jié)構(gòu)類型的變量在內(nèi)存中占的字節(jié)數(shù)是其各個(gè)成員在內(nèi)存中占的字節(jié)數(shù)的總和。要定義一個(gè)結(jié)構(gòu)類型的變量,可以采用以下三種方法。
(3)直接說(shuō)明結(jié)構(gòu)變量struct{inta;floatb;doublec;example*ptr;}x,y;這種方式定義結(jié)構(gòu)變量的一般形式是:struct{成員列表}變量名列表;【例4-8】結(jié)構(gòu)體變量的定義struct{intnum;
charname[20];
charsex;
datebirthday;
floatscore;}boy1,boy2;
structdate{
intmonth;
intday;
intyear;};
首先定義一個(gè)稱之為date結(jié)構(gòu)類型,它由month(月)、day(日)、year(年)三個(gè)成員組成。然后又定義了一個(gè)無(wú)名結(jié)構(gòu)及該結(jié)構(gòu)的兩個(gè)變量boy1、boy2,它包括num、name、sex、birthday、score五個(gè)成員。
需要注意的是:后一個(gè)結(jié)構(gòu)的成員包括date結(jié)構(gòu)變量birthday,這說(shuō)明一個(gè)結(jié)構(gòu)的成員也可以又是另一個(gè)結(jié)構(gòu)的變量,即可構(gòu)成嵌套的結(jié)構(gòu)。二、結(jié)構(gòu)體3、結(jié)構(gòu)體變量的初始化和引用
定義結(jié)構(gòu)變量時(shí),可以同時(shí)初始化它的數(shù)據(jù)成員:
structChild{
doubleheight;doubleweight;intyears;intmonths;chargender;};Childcute={125.0,32.4,2002,2,‘W’};……h(huán)eightweightyearsmonthsgender125.032.420022W二、結(jié)構(gòu)體3、結(jié)構(gòu)體變量的初始化和引用
結(jié)構(gòu)體是由不同類型的成員組成,我們需要使用的是結(jié)構(gòu)變量中的各個(gè)成員。結(jié)構(gòu)變量的使用,包括對(duì)其成員的賦值、輸入、輸出等運(yùn)算?!環(huán)eightweightyearsmonthsgender125.032.420022W
structChild{
doubleheight;doubleweight;intyears;intmonths;chargender;};Childcute={125.0,32.4,2002,2,‘W’};訪問(wèn)結(jié)構(gòu)變量數(shù)據(jù)成員的方式為:結(jié)構(gòu)變量名.成員名cute.heightcute.weightcute.yearscute.monthscute.gender=225.0225.0二、結(jié)構(gòu)體4、結(jié)構(gòu)體數(shù)組
數(shù)組元素也可以是結(jié)構(gòu)體類型。因此可以構(gòu)成結(jié)構(gòu)體數(shù)組。結(jié)構(gòu)體數(shù)組的每一個(gè)元素都是具有相同結(jié)構(gòu)體類型的變量。在實(shí)際應(yīng)用中,經(jīng)常用結(jié)構(gòu)數(shù)組來(lái)表示具有相同數(shù)據(jù)結(jié)構(gòu)的一個(gè)群體。如一個(gè)班的學(xué)生檔案,一個(gè)車間職工的工資表等。二、結(jié)構(gòu)體4、結(jié)構(gòu)體數(shù)組
structstu{intnum;char*name;charsex;floatscore;}boy[]={{101,"Liping","M",45},{102,"Zhangping","M",62.5},{103,"Hefang","F",92.5},{104,"Chengling","F",87},{105,"Wangming","M",58}};例如:當(dāng)對(duì)全部元素作初始化賦值時(shí),也可不給出數(shù)組長(zhǎng)度。5【例4-9】計(jì)算學(xué)生的平均成績(jī)和不及格的人數(shù)。intmain(){inti,c=0;floatave,s=0;for(i=0;i<5;i++){s+=boy[i].score;if(boy[i].score<60)c+=1;}
ave=s/5;printf("平均成績(jī)是:%f\n不及格人數(shù)是:%d\n",ave,c);return0;}structstu{intnum;char*name;charsex;floatscore;}boy[5]={{101,"Liping",'M',45},{102,"Zhangping",'M',62.5},{103,"Hefang",'F',92.5},{104,"Chengling",'F',87},{105,"Wangming",'M',58}};#include<stdio.h>【例4-10】建立同學(xué)通訊錄。#include<stdio.h>#defineNUM3structmem{charname[20];charphone[12];};intmain(){structmemman[NUM];inti;for(i=0;i<NUM;i++){printf("inputname:");gets(man[i].name);printf("inputphone:");gets(man[i].phone);}printf("name\t\t\tphone\n");for(i=0;i<NUM;i++)printf("%-24s%s\n",man[i].name,man[i].phone);return0;}inputname:zhangping↙inputphoneinputname:lihong↙inputphoneinputname:qingwei↙inputphonenamephonezhangpinihoningwe序運(yùn)行結(jié)果如下:二、結(jié)構(gòu)體5、結(jié)構(gòu)體的指針
一個(gè)指針變量當(dāng)用來(lái)指向一個(gè)結(jié)構(gòu)體變量時(shí),便稱之為結(jié)構(gòu)體的指針變量。結(jié)構(gòu)體指針變量中的值是所指向的結(jié)構(gòu)體變量的首地址。通過(guò)結(jié)構(gòu)體指針便可訪問(wèn)該結(jié)構(gòu)體變量的成員,這與數(shù)組指針和函數(shù)指針的情況是相同的。二、結(jié)構(gòu)體5、結(jié)構(gòu)體的指針
定義的一般形式為:struct結(jié)構(gòu)名*指針變量名;structChild*p;(1)指向結(jié)構(gòu)體變量的指針例如:structChild{
doubleheight;doubleweight;intyears;intmonths;chargender;};
結(jié)構(gòu)體類型和結(jié)構(gòu)體變量是兩個(gè)不同的概念,不能混淆。結(jié)構(gòu)體類型就象int、double等類型一樣,是一種數(shù)據(jù)類型,編譯系統(tǒng)并不對(duì)它分配內(nèi)存空間。只有定義了結(jié)構(gòu)類型的變量時(shí),才對(duì)該變量分配存儲(chǔ)空間有了結(jié)構(gòu)指針變量,就能方便地訪問(wèn)結(jié)構(gòu)變量的各個(gè)成員。Child*p=&Child;a;a;二、結(jié)構(gòu)體5、結(jié)構(gòu)體的指針
其訪問(wèn)的一般形式有兩種:structChild*p=&a;(1)指向結(jié)構(gòu)體變量的指針例如:structChild{
doubleheight;doubleweight;intyears;intmonths;chargender;};(*結(jié)構(gòu)指針變量).成員名結(jié)構(gòu)指針變量->成員名a;“.”和“->”運(yùn)算符都稱為成員運(yùn)算符,是訪問(wèn)結(jié)構(gòu)體變量成員的運(yùn)算符,兩個(gè)運(yùn)算符的區(qū)別是,“.”運(yùn)算符是被結(jié)構(gòu)體變量使用,而“->”運(yùn)算符是為結(jié)構(gòu)體變量的指針使用。即他們是訪問(wèn)結(jié)構(gòu)體變量成員的兩種不同形式,一種是通過(guò)變量名訪問(wèn),一種是通過(guò)指針訪問(wèn)。【例4-11】用指針變量輸出結(jié)構(gòu)體變量的成員。#include<stdio.h>structstu{intnum;char*name;charsex;floatscore;}boy1={102,"Zhangping",'M',78.5},*pstu;intmain(){pstu=&boy1;printf("Number=%d\nName=%s\n",boy1.num,);printf("Sex=%c\nScore=%f\n\n",boy1.sex,boy1.score);printf("Number=%d\nName=%s\n",(*pstu).num,(*pstu).name);printf("Sex=%c\nScore=%f\n\n",(*pstu).sex,(*pstu).score);printf("Number=%d\nName=%s\n",pstu->num,pstu->name);printf("Sex=%c\nScore=%f\n\n",pstu->sex,pstu->score);return0;}二、結(jié)構(gòu)體5、結(jié)構(gòu)體的指針
(2)指向結(jié)構(gòu)數(shù)組的指針
指針變量可以指向一個(gè)結(jié)構(gòu)體數(shù)組,這時(shí)結(jié)構(gòu)體指針變量的值是整個(gè)結(jié)構(gòu)體數(shù)組的首地址。結(jié)構(gòu)體指針變量也可指向結(jié)構(gòu)體數(shù)組的一個(gè)元素,這時(shí)結(jié)構(gòu)體指針變量的值是該結(jié)構(gòu)體數(shù)組元素的首地址?!纠?-12】用指針變量輸出結(jié)構(gòu)數(shù)組。voidmain(){structstu*ps;printf("No\tName\t\t\tSex\tScore\t\n");for(ps=boy;ps<boy+5;ps++)printf("%d\t%s\t\t%c\t%f\t\n",ps->num,ps->name,ps->sex,ps->score);}structstu{intnum;char*name;charsex;floatscore;}boy[5]={{101,"Liping",'M',45},{102,"Zhangping",'M',62.5},{103,"Hefang",'F',92.5},{104,"Chengling",'F',87},{105,"Wangming",'M',58}};#include<stdio.h>
應(yīng)該注意的是,一個(gè)結(jié)構(gòu)指針變量雖然可以用來(lái)訪問(wèn)結(jié)構(gòu)變量或結(jié)構(gòu)數(shù)組元素的成員,但是,不能使它指向一個(gè)成員。也就是說(shuō)不允許取一個(gè)成員的地址來(lái)賦予它。ps=&boy[1].sex;
二、結(jié)構(gòu)體5、結(jié)構(gòu)體的指針
(3)結(jié)構(gòu)指針變量作函數(shù)參數(shù)
用結(jié)構(gòu)變量作函數(shù)參數(shù)進(jìn)行整體傳送。這種傳送要將全部成員逐個(gè)傳送,特別是成員為數(shù)組時(shí)將會(huì)使傳送的時(shí)間和空間開(kāi)銷很大,嚴(yán)重地降低了程序的效率。因此最好的辦法就是使用指針,即用指針變量作函數(shù)參數(shù)進(jìn)行傳送。這時(shí)由實(shí)參傳向形參的只是地址,從而減少了時(shí)間和空間的開(kāi)銷?!纠?-13】計(jì)算一組學(xué)生的平均成績(jī)和不及格人數(shù)。用結(jié)構(gòu)指針變量作函數(shù)參數(shù)編程。structstu{intnum;char*name;charsex;floatscore;}boy[5]={{101,"Liping",'M',45},{102,"Zhangping",'M',62.5},{103,"Hefang",'F',92.5},{104,"Chengling",'F',87},{105,"Wangming",'M',58}};voidave(structstu*ps){intc=0,i;floatave,s=0;for(i=0;i<5;i++,ps++){s+=ps->score;if(ps->score<60)c+=1;}ave=s/5;printf("平均成績(jī)是:%f\n不及格人數(shù)是:%d\n",ave,c);}intmain(){structstu*ps;ps=boy;ave(ps);return0;}#include<stdio.h>平均成績(jī)是:69.000000不及格人數(shù)是:2程序運(yùn)行結(jié)果如下:二、結(jié)構(gòu)體6、動(dòng)態(tài)存儲(chǔ)分配
在實(shí)際的編程中,往往會(huì)發(fā)生這種情況,即所需的內(nèi)存空間取決于實(shí)際輸入的數(shù)據(jù),而無(wú)法預(yù)先確定。對(duì)于這種問(wèn)題,用數(shù)組的辦法很難解決。為了解決上述問(wèn)題,C語(yǔ)言提供了一些內(nèi)存管理函數(shù),這些內(nèi)存管理函數(shù)可以按需要?jiǎng)討B(tài)地分配內(nèi)存空間,也可把不再使用的空間回收待用,為有效地利用內(nèi)存資源提供了手段。intn;scanf("%d",&n);inta[n];
在項(xiàng)目三中,我們?cè)谥v數(shù)組類型時(shí),曾強(qiáng)調(diào)過(guò)定義數(shù)組時(shí),下標(biāo)必須為常量,即數(shù)組的長(zhǎng)度必須在定義時(shí)就確定,在整個(gè)程序運(yùn)行過(guò)程中固定不變。C語(yǔ)言中不允許動(dòng)態(tài)數(shù)組類型。例如:二、結(jié)構(gòu)體6、動(dòng)態(tài)存儲(chǔ)分配
常用的內(nèi)存管理函數(shù)有以下三個(gè):
(1)分配內(nèi)存空間函數(shù)malloc調(diào)用形式:(類型說(shuō)明符*)malloc(size)功能:在內(nèi)存的動(dòng)態(tài)存儲(chǔ)區(qū)中分配一塊長(zhǎng)度為“size”字節(jié)的連續(xù)區(qū)域。函數(shù)的返回值為該區(qū)域的首地址?!邦愋驼f(shuō)明符”表示把該區(qū)域用于何種數(shù)據(jù)類型(類型說(shuō)明符*)表示把返回值強(qiáng)制轉(zhuǎn)換為該類型指針?!皊ize”是一個(gè)無(wú)符號(hào)數(shù)。pc=(char*)malloc(100);例如:二、結(jié)構(gòu)體6、動(dòng)態(tài)存儲(chǔ)分配
常用的內(nèi)存管理函數(shù)有以下三個(gè):
(2)分配內(nèi)存空間函數(shù)calloc調(diào)用形式:(類型說(shuō)明符*)calloc(n,size)功能:在內(nèi)存動(dòng)態(tài)存儲(chǔ)區(qū)中分配n塊長(zhǎng)度為“size”字節(jié)的連續(xù)區(qū)域。函數(shù)的返回值為該區(qū)域的首地址?!邦愋驼f(shuō)明符”表示把該區(qū)域用于何種數(shù)據(jù)類型(類型說(shuō)明符*)表示把返回值強(qiáng)制轉(zhuǎn)換為該類型指針?!皊ize”是一個(gè)無(wú)符號(hào)數(shù)。ps=(struetstu*)calloc(2,sizeof(structstu));例如:。
calloc函數(shù)與malloc函數(shù)的區(qū)別僅在于一次可以分配n塊區(qū)域二、結(jié)構(gòu)體6、動(dòng)態(tài)存儲(chǔ)分配
常用的內(nèi)存管理函數(shù)有以下三個(gè):
(3)釋放內(nèi)存空間函數(shù)free調(diào)用形式:free(ptr);功能:釋放ptr所指向的一塊內(nèi)存空間,ptr是一個(gè)任意類型的指針變量,它指向被釋放區(qū)域的首地址。被釋放區(qū)應(yīng)是由malloc或calloc函數(shù)所分配的區(qū)域。ps=(struetstu*)calloc(2,sizeof(structstu));例如:。
【例4-14】分配一塊區(qū)域,輸入一個(gè)學(xué)生數(shù)據(jù)。structstu{intnum;char*name;charsex;floatscore;}*ps;#include<stdio.h>#include<stdlib.h>intmain(){ps=(structstu*)malloc(sizeof(structstu));ps->num=102;ps->name="Zhangping";ps->sex='M';ps->score=62.5;printf("Number=%d\nName=%s\n",ps->num,ps->name);printf("Sex=%c\nScore=%f\n",ps->sex,ps->score);free(ps);return0;}二、結(jié)構(gòu)體7、結(jié)構(gòu)體應(yīng)用-鏈表。
在例4-14中采用了動(dòng)態(tài)分配的辦法為一個(gè)結(jié)構(gòu)體變量分配內(nèi)存空間。每一次分配一塊空間可用來(lái)存放一個(gè)學(xué)生的數(shù)據(jù),我們可稱之為一個(gè)結(jié)點(diǎn)。有n個(gè)學(xué)生就應(yīng)該申請(qǐng)分配n塊內(nèi)存空間,也就是說(shuō)要建立n個(gè)結(jié)點(diǎn)。當(dāng)然用結(jié)構(gòu)數(shù)組也可以完成上述工作,但如果預(yù)先不能準(zhǔn)確把握學(xué)生人數(shù),也就無(wú)法確定數(shù)組大小。而且當(dāng)學(xué)生留級(jí)、退學(xué)之后也不能把該元素占用的空間從數(shù)組中釋放出來(lái)。二、結(jié)構(gòu)體7、結(jié)構(gòu)體應(yīng)用-鏈表。
用動(dòng)態(tài)存儲(chǔ)的方法可以很好地解決這些問(wèn)題。一方面,有一個(gè)學(xué)生就分配一個(gè)結(jié)點(diǎn),無(wú)須預(yù)先確定學(xué)生的準(zhǔn)確人數(shù),某學(xué)生退學(xué),可刪去該結(jié)點(diǎn),釋放該結(jié)點(diǎn)占用的存儲(chǔ)空間,從而節(jié)約了寶貴的內(nèi)存資源。另一方面,用數(shù)組的方法就必須占用一塊連續(xù)的內(nèi)存區(qū)域。而使用動(dòng)態(tài)分配時(shí),每個(gè)結(jié)點(diǎn)之間可以是不連續(xù)的(結(jié)點(diǎn)內(nèi)是連續(xù)的)。結(jié)點(diǎn)之間的聯(lián)系可以用指針實(shí)現(xiàn),即在結(jié)點(diǎn)結(jié)構(gòu)中定義一個(gè)成員項(xiàng)用來(lái)存放下一個(gè)結(jié)點(diǎn)的首地址,這個(gè)用于存放地址的成員,常把它稱為指針域。二、結(jié)構(gòu)體7、結(jié)構(gòu)體應(yīng)用-鏈表。
structstu{intnum;intscore;structstu*next;};例如:一個(gè)存放學(xué)生學(xué)號(hào)和成績(jī)的結(jié)點(diǎn)應(yīng)為以下結(jié)構(gòu)體
前兩個(gè)成員項(xiàng)組成數(shù)據(jù)域,后一個(gè)成員項(xiàng)next構(gòu)成指針域,它是一個(gè)指向stu類型結(jié)構(gòu)的指針變量。鏈表的基本操作對(duì)鏈表的主要操作有以下幾種:(1)建立鏈表;(2)結(jié)構(gòu)體變量(節(jié)點(diǎn))的查找與輸出;(3)插入一個(gè)結(jié)構(gòu)體變量(節(jié)點(diǎn));(4)刪除一個(gè)結(jié)構(gòu)體變量(節(jié)點(diǎn));【例4-15】建立一個(gè)三個(gè)結(jié)點(diǎn)的鏈表,存放學(xué)生數(shù)據(jù)。為簡(jiǎn)單起見(jiàn),我們假定學(xué)生數(shù)據(jù)結(jié)構(gòu)中只有學(xué)號(hào)和年齡兩項(xiàng)。可編寫一個(gè)建立鏈表的函數(shù)Creat。程序如下:#include<stdio.h>#include<stdlib.h>#defineTYPEstructstu#defineLENsizeof(structstu)structstu{intnum;intage;structstu*next;};TYPE*Creat(intn){TYPE*head,*pf,*pb;inti;for(i=0;i<n;i++){pb=(TYPE*)malloc(LEN);printf("input%dNumberandAge\n",i+1);scanf("%d%d",&pb->num,&pb->age);if(i==0)pf=head=pb;elsepf->next=pb;pb->next=NULL;pf=pb;}return(head);}intmain(){intn,i;TYPE*Head,*p;printf("Inputn:");scanf("%d",&n);Head=Creat(n);p=Head;for(i=0;i<n;i++,p=p->next)printf("%d:\nNumber\t%d\nAge\t%d\n",i+1,p->num,p->age);Del(Head);return0;}【例4-15】建立一個(gè)三個(gè)結(jié)點(diǎn)的鏈表,存放學(xué)生數(shù)據(jù)。為簡(jiǎn)單起見(jiàn),我們假定學(xué)生數(shù)據(jù)結(jié)構(gòu)中只有學(xué)號(hào)和年齡兩項(xiàng)??删帉懸粋€(gè)建立鏈表的函數(shù)Creat。程序如下:#include<stdio.h>#include<stdlib.h>#defineTYPEstructstu#defineLENsizeof(structstu)structstu{intnum;intage;structstu*next;};intmain(){intn,i;TYPE*Head,*p;printf("Inputn:");scanf("%d",&n);Head=Creat(n);p=Head;for(i=0;i<n;i++,p=p->next)printf("%d:\nNumber\t%d\nAge\t%d\n",i+1,p->num,p->age);Del(Head);return0;}voidDel(structstu*head){structstu*p,*q;p=q=head;do{p=p->next;free(q);q=p;}while(p!=NULL);}TYPE*Creat(intn){TYPE*head,*pf,*pb;inti;for(i=0;i<n;i++){pb=(TYPE*)malloc(LEN);printf("input%dNumberandAge\n",i+1);scanf("%d%d",&pb->num,&pb->age);if(i==0)pf=head=pb;elsepf->next=pb;pb->next=NULL;pf=pb;}return(head);}structstu{intnum;intage;structstu*next;};建立鏈表;headpfpb100118Inputn:2↙input1NumberandAge100118↙input2NumberandAge100217↙
程序運(yùn)行結(jié)果如下:^100217^100320^
注意動(dòng)態(tài)申請(qǐng)的結(jié)點(diǎn)空間在處理完之后,或程序結(jié)束之前,一定要用free函數(shù)釋放所申請(qǐng)的結(jié)點(diǎn)空間,否則會(huì)造成“內(nèi)存泄漏”問(wèn)題。本程序建立了一個(gè)名為Del的函數(shù),通過(guò)循環(huán)逐一釋放單鏈表中的所有結(jié)點(diǎn)。二、結(jié)構(gòu)體7、結(jié)構(gòu)體應(yīng)用-鏈表三、共用體C語(yǔ)言編程的時(shí)候,為了解決某些問(wèn)題,需要使幾種不同類型的變量存放到同一段內(nèi)存單元中。也就是使用覆蓋技術(shù),幾個(gè)變量互相覆蓋。這種幾個(gè)不同的變量共同占用一段內(nèi)存的結(jié)構(gòu),在C語(yǔ)言中,被稱作“共用體”類型結(jié)構(gòu),簡(jiǎn)稱共用體。共用體是一種構(gòu)造數(shù)據(jù)類型,也叫聯(lián)合體。三、共用體union
共用體類型名{數(shù)據(jù)類型標(biāo)識(shí)符1變量名1;數(shù)據(jù)類型標(biāo)識(shí)符2變量名2;
…………數(shù)據(jù)類型標(biāo)識(shí)符n變量名n;};1、共用體的定義共用體一般定義形式:三、共用體2、共用體變量的定義
共用體類型是不分配內(nèi)存的,但一旦申明變量后就分配內(nèi)存,共用體變量占的內(nèi)存量為最大的成員所占的內(nèi)存量。共用體變量的定義與結(jié)構(gòu)體相同有三種方式定義變量。(1)先定義共用體類型,再定義共用體類型變量。共用體名量名1,變量名2,…,變量名n;uniondata{charch;inti;floatf;};uniondataa,b,c;三、共用體2、共用體變量的定義
共用體類型是不分配內(nèi)存的,但一旦申明變量后就分配內(nèi)存,共用體變量占的內(nèi)存量為最大的成員所占的內(nèi)存量。共用體變量的定義與結(jié)構(gòu)體相同有三種方式定義變量。uniondata{charch;inti;floatf;}a,b,c;(2)在定義共用體類型的同時(shí)定義共用體變量。union共用體名{成員列表}變量名列表;其一般形式為:三、共用體2、共用體變量的定義
共用體類型是不分配內(nèi)存的,但一旦申明變量后就分配內(nèi)存,共用體變量占的內(nèi)存量為最大的成員所占的內(nèi)存量。共用體變量的定義與結(jié)構(gòu)體相同有三種方式定義變量。union{charch;inti;floatf;}a,b,c;(2)在定義共用體類型的同時(shí)定義共用體變量。union{成員列表}變量名列表;其一般形式為:共用體類型數(shù)據(jù)的特點(diǎn):①同一個(gè)內(nèi)存段可以用來(lái)存放幾種不同類型的成員,但是在每一瞬間只能存放其中的一種,而不是同時(shí)存放幾種。換句話說(shuō),每一瞬間只有一個(gè)成員起作用,其他的成員不起作用,即不是同時(shí)都是存在和起作用。
②共用體變量中起作用的成員是最后一次存放的成員,在存入一個(gè)新成員后,原有成員就失去作用。
③共用體變量的地址和它的各成員的地址都是同一地址。
④不能對(duì)共用體變量名賦值,也不能企圖引用變量名來(lái)得到一個(gè)值,并且,不能在定義共用體類型時(shí)對(duì)它的成員賦值。
⑤不能把共用體變量作為函數(shù)參數(shù),也不能是函數(shù)帶回共用體變量,但可以使用指向共用體變量的指針。
⑥共用體類型可以出現(xiàn)在結(jié)構(gòu)體類型的定義中,也可以定義共用體數(shù)組。反之,結(jié)構(gòu)體也可以出現(xiàn)在共用體類型的定義中,數(shù)組也可以作為共用體的成員。三、共用體3、共用體變量的初始化和引用
只有先定義了共用體變量,才能在后續(xù)程序中引用它,引用前可以先對(duì)共用體變量進(jìn)行初始化。(1)共用體變量的初始化注意:對(duì)于共用體變量,在定義的同時(shí),可以初始化,但初始化只能對(duì)第一個(gè)成員初始化。uniondata{charch;inti;floatf;};uniondata
a={65};三、共用體3、共用體變量的初始化和引用
只有先定義了共用體變量,才能在后續(xù)程序中引用它,引用前可以先對(duì)共用體變量進(jìn)行初始化。(2)共用體變量的引用
與結(jié)構(gòu)體變量成員引用的方式相同,也使用“->”和“.”兩種運(yùn)算符來(lái)實(shí)現(xiàn):
有一點(diǎn)需要注意:不能引用共用體變量,而只能引用共用體變量中的成員。共用體變量名.成員名共用體指針變量名->成員名【例4-16】分析下面程序運(yùn)行結(jié)果。uniondata1{charch;inti;floatf;};intmain(){uniondata1ud;structdata2sd;ud.ch='A';ud.i=10;ud.f=20;sd.ch='A';sd.i=10;sd.f=20;printf("sizeofud:%d,sizeofsd:%d\n",sizeof(ud),sizeof(sd));printf("ud.ch:%c\tud.i:%d\tud.f:%f\n",ud.ch,ud.i,ud.f);printf("sd.ch:%c\tsd.i:%d\tsd.f:%f\n",sd.ch,sd.i,sd.f);return0;}#include<stdio.h>structdata2{charch;inti;floatf;};sizeofud:4 sizeofsd:12ud.ch: ud.i:11010048000 ud.f:20.000000sd.ch:A sd.i:10 sd.f:20.000000四、枚舉類型
在實(shí)際問(wèn)題中,有些變量的取值被限定在一個(gè)有限的范圍內(nèi)。例如:一個(gè)星期內(nèi)只有七天,一年只有十二個(gè)月,一個(gè)班每周有六門課程等等。如果把這些量說(shuō)明為整型,字符型或其它類型顯然是不妥當(dāng)?shù)?。為此,C語(yǔ)言提供了一種稱為”枚舉”的類型。在”枚舉”類型的定義中列舉出所有可能的取值,被說(shuō)明為該”枚舉”類型的變量取值不能超過(guò)定義的范圍。應(yīng)該說(shuō)明的是,枚舉類型是一種基本數(shù)據(jù)類型,而不是一種構(gòu)造類型,因?yàn)樗荒茉俜纸鉃槿魏位绢愋?。四、枚舉類型1、枚舉類型的定義和枚舉變量的說(shuō)明(1)枚舉的定義枚舉類型定義的一般形式為:在枚舉值表中應(yīng)羅列出所有可用值。這些值也稱為枚舉元素。
該枚舉名為weekday,枚舉值共有7個(gè),即一周中的七天。凡被說(shuō)明為weekday類型變量的取值只能是七天中的某一天。例如:enumweekday{sun,mou,tue,wed,thu,fri,sat};enum
枚舉類型名{枚舉值1,枚舉值2,…,枚舉值n}四、枚舉類型1、枚舉類型的定義和枚舉變量的說(shuō)明(2)枚舉變量的說(shuō)明
如同結(jié)構(gòu)體和共用體一樣,枚舉變量也可用不同的方式說(shuō)明,即先定義后說(shuō)明,同時(shí)定義說(shuō)明或直接說(shuō)明。例如:enumweekday{sun,mou,tue,wed,thu,fri,sat};enumweekdaya,b,c;設(shè)有變量a,b,c被說(shuō)明為上述的weekday,可采用下述任一種方式:;
enumweekday{sun,mou,tue,wed,thu,fri,sat}a,b,c;enum{sun,mou,tue,wed,thu,fri,sat}a,b,c;四、枚舉類型2、枚舉類型變量的賦值和使用(1)枚舉值是常量,不是變量。不能在程序中用賦值語(yǔ)句再對(duì)它賦值。枚舉類型在使用中有以下規(guī)定:(2)枚舉元素本身由系統(tǒng)定義了一個(gè)表示序號(hào)的數(shù)值。默認(rèn)從0開(kāi)始順序定義為0,1,2…例如:enumnum{one=1,two,three,eight=8,nine,ten};【例4-17】枚舉實(shí)例。#include<stdio.h>intmain(){enumweekday{sun,mon,tue,wed,thu,fri,sat}a,b,c;a=sun;b=mon;c=tue;printf("%d,%d,%d",a,b,c);return0;}0,1,2程序運(yùn)行結(jié)果如下:注意:只能把枚舉值賦予枚舉變量,不能把元素的數(shù)值直接賦予枚舉變量。1;(enumweekday)1;枚舉元素不是字符常量也不是字符串常量,使用時(shí)不要加單、雙引號(hào)。【例4-18】枚舉數(shù)組實(shí)例。#include<stdio.h>intmain(){enumbody{a,b,c,d}month[31],j;inti;j=a;for(i=1;i<=30;i++){month[i]=j;j++;if(j>d)j=a;}for(i=1;i<=30;i++){switch(month[i]){casea:printf("%2d%c\t",i,'a');break;caseb:printf("%2d%c\t",i,'b');break;casec:printf("%2d%c\t",i,'c');break;cased:printf("%2d%c\t",i,'d');break;default:break;}}printf("\n");return0;}
該程序定義了一個(gè)枚舉數(shù)組month,枚舉值為a,b,c,d,通過(guò)循環(huán)為枚舉變量賦予相應(yīng)的枚舉值,最后按一定的格式逐一顯示枚舉變量對(duì)應(yīng)的枚舉值。五、類型定義符
C語(yǔ)言不僅提供了豐富的數(shù)據(jù)類型,而且還允許由用戶自己定義類型說(shuō)明符,也就是說(shuō)允許由用戶為數(shù)據(jù)類型取”別名”。類型定義符typedef即可用來(lái)完成此功能。
用typedef定義數(shù)組、指針、結(jié)構(gòu)等類型將帶來(lái)很大的方便,不僅使程序書寫簡(jiǎn)單而且使意義更為明確,因而增強(qiáng)了可讀性。五、類型定義符例如:typedefcharNAME[20];
表示NAME是字符數(shù)組類型,數(shù)組長(zhǎng)度為20。然后可用NAME說(shuō)明變量:NAMEa1,a2,s1,s2;chara1[20],a2[20],s1[20],s2[20]等價(jià)于五、類型定義符又如:typedefstructstu{charname[20];intage;charsex;}STU;定義STU表示stu的結(jié)構(gòu)類型,然后可用STU來(lái)說(shuō)明結(jié)構(gòu)變量:STUbody1,body2;typedef定義的一般形式為:typedef原類型名新類型名其中原類型名中含有定義部分,新類型名一般用大寫表示,以便于區(qū)別。4.1.3知識(shí)擴(kuò)展:撲克牌發(fā)牌程序
編寫一個(gè)C程序,模擬人工洗牌,將洗好的52張牌隨機(jī)發(fā)給4個(gè)人。
這是一個(gè)典型的結(jié)構(gòu)體應(yīng)用的C程序。這里對(duì)于每一張撲克牌存在著花色和點(diǎn)數(shù)兩個(gè)數(shù)據(jù)信息,所以我們需要選擇使用自定義的結(jié)構(gòu)類型來(lái)描述,我們定義了一個(gè)名為card的結(jié)構(gòu)來(lái)描述一張牌,用這個(gè)結(jié)構(gòu)的數(shù)組描述52張牌,然后使用自定義函數(shù)swapcard和shuffle,來(lái)模擬人工洗牌的隨機(jī)過(guò)程,最后將洗好的牌順序地分發(fā)給4個(gè)人。這里的核桃、紅心、梅花、方塊圖形是屬于ASCII中輸出的字符,紅心對(duì)應(yīng)3、方塊對(duì)應(yīng)4,梅花對(duì)應(yīng)5,核桃對(duì)應(yīng)6。任務(wù)2數(shù)據(jù)文件的存取數(shù)據(jù)文件的存取#include<stdio.h>#include<stdlib.h>#include<string.h>typedefstructaddress{charname[18];chartel[20];structaddress*next;}ADDR;4.2.1問(wèn)題情景及其實(shí)現(xiàn)
設(shè)計(jì)一個(gè)通訊錄人員信息結(jié)構(gòu)體,錄入通訊錄中多名人員的信息實(shí)現(xiàn)通過(guò)相關(guān)的數(shù)據(jù)文件進(jìn)行讀取和保存。輸入人員姓名:張三↙輸入人員電話文件tel.txt保存成功程序運(yùn)行結(jié)果:intmain(){FILE*fp;if((fp=fopen("tel.txt","wt+"))==NULL){printf("不能打開(kāi)文件!\n");}else{ADDR*h;h=(ADDR*)malloc(sizeof(ADDR));printf("輸入人員姓名:");scanf("%s",h->name);printf("輸入人員電話:");scanf("%s",h->tel);h->next=NULL;fprintf(fp,"%s\t%s\n",h->name,h->tel);printf(“文件tel.txt保存成功\n”);free(h);fclose(fp);
}return0;}4.2.2知識(shí)分解C文件的概念C文件的有關(guān)操作一、文件的概念
所謂“文件”是指一組相關(guān)數(shù)據(jù)的有序集合。這個(gè)數(shù)據(jù)集有一個(gè)名稱,叫做文件名。實(shí)際上在前面的項(xiàng)目中我們已經(jīng)多次使用了文件,例如源程序文件、目標(biāo)文件、可執(zhí)行文件、庫(kù)文件(頭文件)等。1、C文件概念
文件通常是駐留在外部介質(zhì)(如磁盤等)上的,在使用時(shí)才調(diào)入內(nèi)存中來(lái)。對(duì)于C程序文件,按其編碼方式分為ASCII碼文件和二進(jìn)制碼文件兩種。一、文件的概念1、C文件概念A(yù)SCII文件也稱為文本文件,這種文件在磁盤中存放時(shí)每個(gè)字符對(duì)應(yīng)一個(gè)字節(jié),用于存放對(duì)應(yīng)的ASCII碼。ASCII碼文件可在屏幕上按字符顯示,例如源程序文件就是ASCII文件。
二進(jìn)制文件是按二進(jìn)制的編碼方式來(lái)存放文件的。二進(jìn)制文件雖然也可在屏幕上顯示,但其內(nèi)容無(wú)法讀懂。C系統(tǒng)在處理這些文件時(shí),并不區(qū)分類型,都看成是字符流,按字節(jié)進(jìn)行處理。一、文件的概念2、文件的指針
在C語(yǔ)言中用一個(gè)指針變量指向一個(gè)文件,這個(gè)指針?lè)Q為文件指針。通過(guò)文件指針就可對(duì)它所指的文件進(jìn)行各種操作。
其中FILE應(yīng)為大寫,它實(shí)際上是由系統(tǒng)定義的一個(gè)結(jié)構(gòu),該結(jié)構(gòu)中含有文件名、文件狀態(tài)和文件當(dāng)前位置等信息。在編寫源程序時(shí)不必關(guān)心FILE結(jié)構(gòu)的細(xì)節(jié)。定義說(shuō)明文件指針的一般形式為:FILE*指針變量標(biāo)識(shí)符;FILE*fp;例如:
表示fp是指向FILE結(jié)構(gòu)的指針變量,通過(guò)fp即可找存放某個(gè)文件信息的結(jié)構(gòu)變量,然后按結(jié)構(gòu)變量提供的信息找到該文件,實(shí)施對(duì)文件的操作。習(xí)慣上也籠統(tǒng)地把fp稱為指向一個(gè)文件的指針。二、文件的有關(guān)操作1、文件的打開(kāi)與關(guān)閉
文件在進(jìn)行讀寫操作之前要先打開(kāi),使用完畢要關(guān)閉。打開(kāi)文件是建立文件的各種有關(guān)信息,并使文件指針指向該文件,以便進(jìn)行其它操作。關(guān)閉文件則斷開(kāi)指針與文件之間的聯(lián)系,也就禁止再對(duì)該文件進(jìn)行操作。在C語(yǔ)言中,文件操作都是由庫(kù)函數(shù)來(lái)完成的。二、文件的有關(guān)操作1、文件的打開(kāi)與關(guān)閉
(1)文件的打開(kāi)(fopen函數(shù))其調(diào)用的一般形式為:文件指針名=fopen(文件名,使用文件方式);其中:“文件指針名”必須是被說(shuō)明為FILE類型的指針變量;“文件名”是被打開(kāi)文件的文件名;“使用文件方式”是指文件的類型和操作要求。二、文件的有關(guān)操作1、文件的打開(kāi)與關(guān)閉
(1)文件的打開(kāi)(fopen函數(shù))其調(diào)用的一般形式為:文件指針名=fopen(文件名,使用文件方式);對(duì)于文件使用方式有以下幾點(diǎn)說(shuō)明:①文件使用方式由r,w,a,t,b,+六個(gè)字符拼成,各字符的含義是:r(read):讀w(write):寫a(append):追加t(text):文本文件,可省略不寫b(banary):二進(jìn)制文件+:讀和寫二、文件的有關(guān)操作1、文件的打開(kāi)與關(guān)閉
(1)文件的打開(kāi)(fopen函數(shù))其調(diào)用的一般形式為:文件指針名=fopen(文件名,使用文件方式);對(duì)于文件使用方式有以下幾點(diǎn)說(shuō)明:②凡用”r”打開(kāi)一個(gè)文件時(shí),該文件必須已經(jīng)存在,且只能從該文件讀出。③用”w”打開(kāi)的文件只能向該文件寫入。若打開(kāi)的文件不存在,則以指定的文件名建立該文件,若打開(kāi)的文件已經(jīng)存在,則將該文件刪去,重建一個(gè)新文件。④若要向一個(gè)已存在的文件追加新的信息,只能用”a”方式打開(kāi)文件。但此時(shí)該文件必須是存在的,否則將會(huì)出錯(cuò)。二、文件的有關(guān)操作1、文件的打開(kāi)與關(guān)閉
(1)文件的打開(kāi)(fopen函數(shù))其調(diào)用的一般形式為:文件指針名=fopen(文件名,使用文件方式);對(duì)于文件使用方式有以下幾點(diǎn)說(shuō)明:⑤在打開(kāi)一個(gè)文件時(shí),如果出錯(cuò),fopen將返回一個(gè)空指針值NULL。在程序中可以用這一信息來(lái)判別是否完成打開(kāi)文件的工作,并作相應(yīng)的處理。因此常用一個(gè)if判斷語(yǔ)句來(lái)打開(kāi)文件;if((fp=fopen("c:\\hzk16","rb")==NULL){printf("\nerroronopenc:\\hzk16file!");getch();exit(1);}
如果fopen函數(shù)返回的指針為空,則不能打開(kāi)c盤根目錄下的hzk16文件,則給出提示信息”erroronopenc:\hzk16file!”,然后通過(guò)getch()函數(shù)的功能等待用戶從鍵盤敲任一鍵,程序繼續(xù)執(zhí)行,用戶可利用這個(gè)等待時(shí)間閱讀出錯(cuò)提示。敲鍵后執(zhí)行exit(1)退出程序。二、文件的有關(guān)操作1、文件的打開(kāi)與關(guān)閉
(2)文件關(guān)閉函數(shù)(fclose函數(shù))其調(diào)用的一般形式為:fclose(文件指針
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 專業(yè)工業(yè)廠房買賣合同范本
- 合同范本彩鋼棚
- 公家車庫(kù)出租合同范本
- 發(fā)廊股東協(xié)議合同范本
- 北京中開(kāi)合同范本
- 合建房合同范本
- 勞動(dòng)合同范本企業(yè)
- 從化醫(yī)院食堂承包合同范本
- 項(xiàng)目合作定金合同范本
- 合同范本范本
- 六年級(jí)上冊(cè)英語(yǔ)教案-Culture 2 Going Green 第二課時(shí) 廣東開(kāi)心英語(yǔ)
- 警察叔叔是怎樣破案的演示文稿課件
- 2019石景山初三一模語(yǔ)文試題及答案
- 外固定架課件
- 尿液有形成分形態(tài)學(xué)檢查與臨床意義課件
- 保密風(fēng)險(xiǎn)評(píng)估報(bào)告
- 09式 新擒敵拳 教學(xué)教案 教學(xué)法 圖解
- CAD術(shù)語(yǔ)對(duì)照表
- 《橋梁工程計(jì)算書》word版
- 學(xué)術(shù)論文的寫作與規(guī)范課件
- 香港牛津新魔法Newmagic3AUnit4Mycalendar單元檢測(cè)試卷
評(píng)論
0/150
提交評(píng)論