高级语言程序设计课件_第1页
高级语言程序设计课件_第2页
高级语言程序设计课件_第3页
高级语言程序设计课件_第4页
高级语言程序设计课件_第5页
已阅读5页,还剩266页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

C語言的基本控制結構一、順序結構二、關係運算和邏輯運算三、選擇結構四、迴圈結構一、順序結構程式是按書寫順序執行的#include<stdio.h>main(){inti,sum; /*定義變數*/sum=0; /*為變數sum賦初值0*/for(i=1;i<=100;i++){ /*計算1~100的整數和*/sum=sum+i;}printf("\n1+2+3+...+99+100=%d",sum); /*輸出計算結果*/}二、關係運算和邏輯運算關係運算符:><>=<===!=邏輯運算符:&&||!優先順序和結合性?條件運算式寫法例子整型變數month代表月份,應該在1~12之內,如何寫判斷合法性的運算式?1<=month&&month<=12

不可以寫成:1<=month<=12

判斷相等的運算式1==month或者month==1

運算式的值關係運算式與邏輯運算式運算式成立,其值1運算式不成立,其值為0(3<5)+(2<4)值為2三、選擇結構if(條件) 語句1else

語句2條件語句1語句2是否例:求整數的絕對值#include<stdio.h>main(){ intinput,output; printf("\nEnterainteger:"); scanf("%d",&input);/*判斷input是否小於0 */ if(input<0) output =-input; else output =input; printf("ABS(%d)=%d\n",input,output);}複雜一點的選擇結構if(條件)

if(條件) 語句1else

語句2else

語句2if(條件) 語句1elseif(條件)

語句2…else語句2例:鍵盤輸入座標,判象限#include<stdio.h>main(){ intx,y; printf("\nEnter2integers:"); scanf("%d%d",&x,&y);

if(x>0){

if(y>0) printf("Iquadrant\n"); else printf("VIquadrant\n");

}else{

if(y>0) printf("IIquadrant\n"); else printf("IIIquadrant\n");

}}例:鍵盤輸入座標,判象限//換一種寫法#include<stdio.h>main(){ intx,y; printf("\nEnter2integers:"); scanf("%d%d",&x,&y); if(x>0&&y>0) printf("Iquadrant\n"); elseif(x>0&&y<0) printf("VIquadrant\n"); elseif(x<0&&y>0) printf("IIquadrant\n"); elseif(x<0&&y<0) printf("IIIquadrant\n");}switch(運算式){ case常量1:語句1 case常量2:語句2 …… case常量n:語句n default:語句n+1}運算式語句1…語句2語句ndefaultcase中的常量只能是:整型、字元型或枚舉,與運算式的值嚴格匹配。閱讀P40下麵部分多路選擇與switch語句例:鍵盤輸入座標,判象限#include<stdio.h>main(){ intx,y; printf("\nEnter2integers:"); scanf("%d%d",&x,&y); switch(2*(x>0)+(y>0)) { case3: printf("Iquadrant\n"); break; case2: printf("VIquadrant\n"); break; case1:printf("IIquadrant\n"); break; case0:printf("IIIquadrant\n"); break; default: printf("error!"); } }總結可以一路選擇,二路選擇,多路選擇測試要涉及到每個程式執行路徑注意複合語句的應用自學[P41,例2-3]自學[P42,例2-4]四、迴圈結構while

(運算式) 循環體條件循環體是否注意幾點:迴圈開始迴圈結束迴圈語句步進例:P45,例2-5請編寫一個程式,其功能為:從鍵盤輸入1000個整數,計算它們的平均值。分析數據結構定義迴圈變數:inti存儲和:intsum,初值為0接收輸入的每個值:intx迴圈開始:i=1迴圈結束:i<=1000循環體:輸入數據、累加數據、步進#include<stdio.h>main(){ intsum=0,i=1;intx; printf("\nEnter1000integers:"); while(i<=1000){ scanf("%d",&x); i++; sum=sum+x; } printf("Theaveragevalueis%lf\n",sum*1.0/(i-1));}注意迴圈語句執行結束後,迴圈變數的值為什麼用常量1.0,而不是1for

(運算式1;運算式2;運算式3) 循環體運算式2運算式1是否循環體運算式3初值結束步進例:P45,例2-5請編寫一個程式,其功能為:從鍵盤輸入1000個整數,計算它們的平均值。分析定義迴圈變數:inti存儲和:intsum,初值為0接收輸入的每個值:intx迴圈開始:i=1迴圈結束:i<=1000循環體:輸入數據、累加數據、步進#include<stdio.h>main(){ intsum=0,i;intx; printf("\nEnter1000integers:"); for(i=1;i<=1000;i++){ scanf("%d",&x); sum=sum+x; } printf("Theaveragevalueis%lf\n",sum*1.0/(i-1));}自學[P47,例2-6]do

語句while

(運算式)條件循環體是否例:P45,例2-5請編寫一個程式,其功能為:從鍵盤輸入1000個整數,計算它們的平均值。分析定義迴圈變數:inti存儲和:intsum,初值為0接收輸入的每個值:intx迴圈開始:i=1迴圈結束:i<=1000循環體:輸入數據、累加數據、步進#include<stdio.h>main(){ intsum=0,i=1;intx; printf("\nEnter1000integers:"); do{ scanf("%d",&x); sum=sum+x; i++; }while(i<=1000); printf("Theaveragevalueis%lf\n",sum*1.0/(i-1));}例:輸入x值,並計算

inti; intx,result=1; printf("請輸入x的值(x>0):"); scanf("%d",&x); for(i=0;i<x;i++) result=result*2; printf("\nresult=%d\n",result);輸入30、31,測試整數的可能的溢出例自學[P48,例2-7]自學[P49,例2-8]第6章數據的組織結構(二)一、結構體二、指針和引用三、動態申請存儲空間四、不同類型的函數參數總結五、鏈表六、檔七、聯合體與枚舉類型

一、結構體如何表示多個不同類型的資料項目,這些資料項目邏輯上構成一個數據元素?如:每個學生都有學號、姓名每本書都有書號、書名、作者、出版社用結構體類型來表示。struct<結構體類型名>{ <數據類型><成員1>; <數據類型><成員1>;…… <數據類型><成員n>;};structpoint{ intx;inty;};structstudent{ intsNum;charname[10];};結構體類型聲明聲明的是數據類型,不是變數!pointp1,p2;//對比:inti,j;studentzhang,wang;定義時初始化pointp1={1,1};studentzhang={1,"張一"};結構體類型變數定義p1p1p111zhang1張一整型大小10個字元大小結構體類型變數的成員變數的引用<結構體變數名>.<成員名>p1.xp1.yzhang.sNum即看成普通變數使用scanf("%d%d",&p1.x,&p1.y);scanf("%s",);printf("%s",);p1.x=1;="張一";同一結構體類型變數可以賦值pointp1={1,2},p2;p2=p1;等同於:p2.x=p1.x;p2.y=p1.y;例:學生基本資訊的組織學生資訊:學號、姓名、出生日期、所屬院系、專業完成任務鍵盤輸入30個學生的資訊、並螢幕輸出;鍵盤輸入月份和日期,查找並輸出本年度在給定日期之後過生日的學生資訊例:學生基本資訊的組織設計數據結構:每個學生基本資訊用結構體描述學號intnum;姓名charname[24];出生日期自定義一個結構:年、月、日所屬院系chardepartment[48];專業charmajor[32];structDate{ /*日期結構*/ intyear;intmonth;intday;};structStudentInfo{ /*學生資訊結構*/intnum;charname[24];Datebirthday;chardepartment[48];charmajor[32];};數據類型的別名用戶可以為已有的數據類型起別名語法:typedef

原數據類型新的數據類型名例如:typedefintxuehao;思考這樣做的好處?程式更加清晰易懂日期Date和學生資訊StudentInfo結構的另一種定義方式:typedefstruct{ /*日期結構*/ intyear;intmonth;intday;}Date;typedefstruct{ /*學生資訊結構*/intnum;charname[24];Datebirthday;chardepartment[48];charmajor[32];}StudentInfo;30名學生用數組表示#defineNUM30StudentInfos[NUM];程式結構設計給出每個函數的定義,包括:功能說明,入口參數,出口參數等。主模組main()輸入模組inputIofo()查詢處理模組searchInfo()輸出模組outputInfo輸入模組voidinputInfo(StudentInfo[]);功能:將全部學生資訊通過鍵盤輸入到StudentInfo[]數組。參數:學生資訊數組。返回值:沒有。輸出模組voidoutputInfo(StudentInfo[]);功能:格式化輸出StudentInfo[]數組中的全部學生資訊。參數:學生資訊數組。返回值:沒有。查詢處理模組voidsearchInfo(StudentInfo[],DATE);功能:查找並輸出StudentInfo[]數組中,DATE之後過生日的學生資訊。參數:學生資訊數組。查找關鍵字:Date返回值:沒有。依據定義設計函數的流程,編寫代碼。編寫主模組函數的代碼。看書P170,程式代碼。分析書中設計的優缺點?結構體應用例題P172,鍵盤輸入10個整數,將它們從小到大重新排序,要求輸出排序後的結果和排序前的位置數據結構用結構體類型將整數和原始位置綁在一起typedefstruct{intdata; /*整型數值*/intpos; /*原始位置*/}DATATYPE;演算法輸入:針對本次任務修改輸出:針對本次任務修改排序:用以前的函數例:模擬發撲克牌數據結構一張撲克牌的表示一副撲克牌的表示演算法初始化一副撲克牌洗牌發牌P175二、指針指針類型變數的定義<數據類型>*<指針類型變數名>int*intptr;char*chptr;intptr0x0012ff78一個地址大小chptr0x0012ff70一個地址大小指針是變數是地址變數指針類型變數的引用int*intptr;char*chptr;inti=0;charc=‘a’;intptr=&i;//i的地址賦給intptrchptr=&c;//c的地址賦給chptrintptr0x0012ff780x0012ff78chptr0x0012ff700x0012ff700aint*intptr;char*chptr;inti=0;charc=‘a’;intptr=&i;chptr=&c;

ci指針變數所指的值*intptr=30;在格式化輸入輸出中的應用printf(“%d,%c”,*intptr,*chptr);scanf(“%d%c”,intptr,chptr);intptr30intptr1intptr2NULL指針變數可初始化為空指針int*intptr1=&i;int*intptr2=NULL;指針賦值intptr2=intptr1;i指針比較if(intptr2==intptr1)

…if(intptr2==NULL)

…if(!intptr2)

…指針加減int*p=data;//p指向data[0];即:&data[0]p++;//p指向data[1];p=p+2;//p指向data[3];p=p-2;//p指向data[1];p=p+12;//成為bug;0123456789dataintdata[10];例char*strchr(char*s,charc)函數確定某個字元在字串中出現的位置s是字串,c要找的字元strchr函數返回指向找到的字元的指針用此函數獲取指定字元在字串中的位置數目chars[]="1236.87";intp;p=strchr(s,'.')-s+1;printf("位置在:%d\n",p);

strchr函數返回指針,指針相減定位位置例#include"stdio.h"#include"string.h"intmain(intargc,char*argv[]){ charb[]="Goodbye"; char*pb=&b[7]; while(--pb>=&b[0]) putchar(*pb); putchar('\n'); return0;}

逆序為什麼指針變數也要有類型?指針變數所存地址沒有區別但對指針變數所存地址指向的數據的操作不同(不同數據集合上定義的操作不同,如:指針加1的操作)指針可指向各種數據類型,如基本類型、數組、函數、對象、指針等指針與數組數組名是指向數組第1個元素的指針,但這個指針是常量; charstr[]={"program"}; printf(“%c\n”,*str); //列印p printf(“%c\n”,*++str);//錯 printf(“%c\n”,*(1+str));//對 char*p;p=str; printf(“%c\n”,*++p);//列印r指針與數組數組名定位數組元素P184圖6-14指針定位數組元素P184圖6-15利用指針對數組元素進行操作intiarray[20];int*ptr;//方法一for(ptr=iarray,i=0;i<20;i++)printf(“%d”,*(ptr+i));//方法二for(ptr=iarray;ptr<iarray+20;ptr++)printf(“%d”,*ptr);例6-4P185指針數組例子//列印整型數組指定的行。j:行號(0開始),rowD:行長度,p:指向數組第一個元素的指針voidpr_row(intj,introwD,int*p){inti;

p=p+(j*rowD);for(i=0;i<rowD;i++)printf(“%d”,*(p+i));}二維數組與一維指針數組inta[3][2];a[0][0]a[0][1]a[1][0]a[1][1]a[2][0]a[2][1]a[0]a[0]a[1]a[2]二維數組與一維指針數組inta[3][2];a[0][0]a[0][1]a[1][0]a[1][1]a[2][0]a[2][1]a[0]a[1]a[2]a[0],a[1],a[2],一維數組的首地址,是指針。用指針定位二維數組元素:i代表行,j代表列int*ptr=a[0];元素:*(ptr+i*列數+j)例:P187#defineROWNUM5#defineCOLNUM4 inta[ROWNUM][COLNUM]; int*ptr1;

ptr1=a[0]; for(i=0;i<ROWNUM;i++){ for(j=0;j<COLNUM;j++) printf("%3d",*(ptr1+i*COLNUM+j)); printf("\n"); }可替換:ptr1=&a[0][0];ptr1=(int*)a;例:P187

int(*ptr2)[COLNUM];

ptr2=&a[0];//a[0]是指針,可以:ptr2=a; for(i=0;i<ROWNUM;i++){ for(j=0;j<COLNUM;j++) printf("%3d",*(*(ptr2+i)+j)); printf("\n"); }書錯int(*ptr2)[COLNUM];

與int*ptr2[COLNUM];區別int*ptr2[COLNUM];//是整型指針的數組int(*ptr2)[COLNUM];//指向整型指針的指針數組指針數組inta[10];int*b[3];b[0]=&a[0];for(i=0;i<10;i++)printf("%3d",*(b[0]+i));b是一個指向指針的指針。0123456789ab書學習書P188,例6-5指向指針的指針變數float**p;地址p地址值main(){intx,*p,**q;x=0;p=&x;q=&p;

printf("%d",**q);//列印x的值}指針與字串字元數組名是字元數組首地址,字串需要有字串結束符。charname[10]="zhang";char*chptr=name;printf("%s",name);printf("%s",chptr);指針與字串例子庫函數strcmp()intstrcmp(char*s1,char*s2){while(*s1)//直到s1字串結尾才falseif(*s1-*s2)return*s1-*s2;

else{s1++;s2++;}return0;}例子:找出程式的錯誤main(){char*p,s[80];p=s;do{gets(s);while(*p)printf(“%c”,*p++);}while(strcmp(s,“done”));}例子:正確答案main(){char*p,s[80];do{

p=s;gets(s);while(*p)printf("%c",*p++);}while(strcmp(s,"done"));}指向結構體變數的指針定義structStudent{intnumber;

char*next;};使用Studentzhang,*p;zhang

={1,”zhangbo”};p=&zhang;printf("%d",p->number);//等價:printf("%d",zhang.number);例:選舉問題選舉問題:某部門,需要由全體員工推選一名辦公室主任。假設有10名候選人。編程序依據每個候選人的得票數量,得票最多當選,給出選舉結果包括候選人編號和得票數。定義結構體:structCandidate{ intnumber;//候選人號碼

intvote;//候選人得票數};intmain(){Candidatedata[NUM]; CandidateMySelected; input(data,NUM); MySelected=max(data,NUM); output(MySelected); return0;}/*查找得票最多的候選人。參數…,返回值…。*/Candidatemax(Candidatevalue[],intn){ inti; Candidateselected; selected.vote=value[0].vote; selected.number=value[0].number; for(i=1;i<n;i++) { if(value[i].vote>selected.vote){ selected.vote=value[i].vote; selected.number=value[i].number; }} returnselected;}voidoutput(Candidateselected){ printf("當選者是%d候選人。得票數%d。\n",selected.number,selected.vote); return;}voidinput(Candidatevalue[],intn){ inti; printf("請輸入%d個候選人的號碼:",n); for(i=0;i<n;i++) { scanf("%d",&value[i].number);} printf("請輸入%d個候選人的得票數:",n); for(i=0;i<n;i++) { scanf("%d",&value[i].vote);}}結構體成員是結構體變數的指針structnode{intdata;

node*next;};nodea,*p;

a={1,NULL};p=&a;printf("%d",p->data);//等價:printf("%d",a.data);三、動態申請存儲空間庫函數中動態申請和釋放存儲空間的函數,包含:stdlib.hvoid*malloc(intsize)//申請voidfree(void*p)//釋放例:int*ptr=(int*)malloc(sizeof(int)*20);free(ptr);

為什麼叫動態記憶體分配?數組:inta[10];//靜態記憶體分配動態申請記憶體空間存儲數組int*ptr=(int*)malloc(sizeof(int)*10);比較:程式運行到此語句才分配記憶體空間必須釋放注意記憶體洩漏例6-6,P190,構造楊輝三角形a……分析題目,設計數據結構一維整型指針數組動態生成整型數組空間四、引用引用類型變數定義:int&a;//變數的別名用法:int&a;a=0;與地址相關的運算符:*&int*p;//聲明p是一個int型指針inti=0;int&rf=i;//聲明一個int型的引用,rf存int型數據的地址,//所以int&rf=0錯,但可以intrf(0);p=&i;printf("%d\n",*p);//指針p所指的內容,*是指針運算符printf("%d\n",(*p)++);//指針p所指的內容加1printf("%d\n",*p);printf("%d\n",rf);//rf此時用i的值rf++;//引用數據加1p=&rf;printf("%d\n",*p);五、再談函數和函數參數值傳遞:變數值做函數參數voidexchang1(intx,inty){ints;s=x;x=y;y=s;}main(){intt1=1,t2=2;exchange1(t1,t2);}Exchange1中對x,y的改變不影響t1,t2的值。實際沒有完成交換功能。結論:值傳遞時,被調用函數中對參數值的改變,不影響調用它的函數實參的值。地址傳遞:指針變數做函數參數voidexchang3(int*x,int*y){ints;s=*x;*x=*y;*y=s;}main(){intt1=1,t2=2;exchange3(&t1,&t2);}Exchange3中對x,y所指值的改變使t1,t2的值發生改變。完成了交換功能。結論:地址傳遞時,被調用函數中對參數值的改變,將影響調用它的函數實參的值。引用變數做函數參數voidexchang2(int&x,int&y){ints;s=x;x=y;y=s;}main(){intt1=1,t2=2;exchange2(t1,t2);}Exchange2中對x,y的改變使t1,t2的值發生改變。完成了交換功能。結論:地址傳遞時,被調用函數中對參數值的改變,將影響調用它的函數實參的值。數組做函數參數voidexchang4(char*a,char*b){chars[5];strcpy(s,a);strcpy(a,b);strcpy(b,s);}main(){ chart3[5]="aaa"; chart4[5]="bbb";exchang4(t3,t4);}

Exchange4中對a,b的值改變使t3,t4的值發生改變。完成了交換功能。

利用函數返回值例題intmain(){chara;while(1){scanf("%c",&a);getchar();if(fun(a)==-1){printf("出現異常\n");break;}elseprintf("%c\n",a);}return0;}intfun(char&c){if(c>='a'-1&&c<'z'){c++;//處理creturn0;}elsereturn-1;}指針型函數函數的返回值為指針(P199代碼)char*strsub(char*str,intstart,intlen){ inti,num;char*p; if(strlen(str)<start) returnNULL; if(strlen(str)<start+len) num=strlen(str)–start; else num=len; p=(char*)malloc(sizeof(char)*(num+1)) for(i=0;i<num;i++) *(p+i)=*(str+start+i); *(p+i)=‘\0’; returnp;}選舉的例子(教育線上課件資料中有完整的例子)intmain(){intn=NUM;

int*data;intMySelected;input(&data);MySelected=max(data,n);output(MySelected);return0;}intinput(int**value){inti;*value=(int*)malloc(sizeof(int)*NUM);if(!*value)return-1;//-1代表申請存儲空間失敗printf("請輸入%d個整型數:",NUM);for(i=0;i<NUM;i++){ scanf("%d",*value+i);}return0;//函數成功返回}錯誤例子,錯在哪里?intmain(){intn=NUM;

int*data;intMySelected;input(data);MySelected=max(data,n);output(MySelected);return0;}intinput(int*value){inti;value=(int*)malloc(sizeof(int)*NUM);if(!value)return-1;//-1代表申請存儲空間失敗printf("請輸入%d個整型數:",NUM);for(i=0;i<NUM;i++){ scanf("%d",value+i);}return0;//函數成功返回}六、鏈表目的:練習指針,初識數據結構。需要存儲數據:(a1,a2,…an),使用怎樣的數據結構?答案:數組。intdata[N];如果元素的個數在[1,n]之間動態變化,甚至可能超過n,使用怎樣的數據結構?答案:動態生成數組。p=(int*)malloc(sizeof(int)*N);仍然要確定存儲空間大小。使用鏈表結構單鏈表鏈表特點:不必預知元素多少相鄰元素存儲空間不必連續數組特點:預知元素多少,且變化不大的連續的存儲空間a1La2an…構建單鏈表分析必須有L,稱之為頭指針鏈表中每個元素,稱之為結點,每個結點必須存儲數據和指向下一個結點的指針最後一個結點,沒有後繼,為空指針空的單鏈表暫時沒有元素構建單鏈表基礎a1La2an…LNULL結點的定義:例如元素為整型數據structnode{intdata;

node*next;};由此聯想數據處理操作:迴圈開始:頭指針指向第一個元素迴圈中:前驅指向後繼迴圈結束:空指針a1La2an

^…構建單鏈表方法一:尾插法總是插入到當前鏈表的表尾,直到讀入結束標誌為止。正序輸入數據a1a2a3^L在此插入思路:定義頭指針建立a1結點,賦頭指針建立後面結點插入鏈表尾voidCreateList_E(node*L)//正序輸入元素的值,建立單鏈表L{node*p,*s;L=(node*)malloc(sizeof(node));

scanf(("%d",&(L->data));L->next=NULL;//先建立第一個結點p=L;while(結束條件運算式){s=(node*)malloc(sizeof(node));scanf(("%d",&(s->data));

s->next=NULL;

p->next=s;p=s;

}}//CreateList_E帶頭結點的單鏈表:為了使所有元素統一處理方式,專門加一個頭結點帶頭結點的空鏈表a1a2an∧a3L…..∧LvoidCreateList_E(node*L)//正序輸入元素的值,建立帶頭結點的單鏈表L{node*p,*s;L=(node*)malloc(sizeof(node));

L->next=NULL;//先建立一個帶頭結點的單鏈表p=L;while(結束條件運算式){s=(node*)malloc(sizeof(node));scanf(("%d",&(s->data));s->next=NULL;

p->next=s;p=s;}}//CreateList_E構建單鏈表方法二:頭插法 該方法從一個空表開始,重複讀入數據,生成新結點,將讀入數據存放到新結點的數據域中,然後將新結點插入到當前鏈表的頭指針上,直到讀入結束標誌為止。a1a2an∧a3L…..在此插入應逆序插入頭結點voidCreateList_L(node*L)//逆序輸入n個元素的值,建立帶頭結點的單鏈表L{node*p;L=(node*)malloc(sizeof(node));

L->next=NULL;//先建立一個帶頭結點的空的單鏈表 for(i=

n;i>0;--i){ p=(node*)malloc(sizeof(node));//生成新結點scanf(("%d",&(p->data));p->next=L->next;//插入到表頭L->next=p;}}//createList_L體會有頭結點的好處例:計算鏈表結點的個數intListLength(node*L)//帶頭結點{node*p;p=L; intlen=0; for(;p!=NULL;p=p->next) len++; returnlen;}a1a2an∧a3L…..插入鏈表結點在第i個元素前插入一個新元素x首先找到ai-1的存儲位置p生成一個數據域為x的新結點*s插入過程先做:s->next=p->next再做:p->next=s5353xPPSai-1ai12intListInsert_L(node*L,inti,intx){node*s,*p=L;intj=0;while(p&&j<i-1)//注意是兩個條件

{p=p->next;++j;}//尋找第i-1結點

if(!p||j>i-1) return-1;//i小於1或大於(表長+1)

s=(node*)malloc(sizeof(node));//生成新結點

s->data=x; s->next=p->next; p->next=s;return0;}∧anaia1a2ai-1xL刪除鏈表結點刪除運算是將表的第i個結點刪去。思路首先找到ai-1的存儲位置pq=p->next,為處理被刪除結點做準備刪除操作:p->next=q->next處理q所指結點ai-1a1aiai+1LpqintListDelete_L(node*L,inti,int&e){ node*q,*p=L;intj=0; while(p->next&&j<i-1) {p=p->next;++j;}//尋找第i-1結點

if(!(p->next)||j>i-1)return-1;//刪除位置不合理

q=p->next;p->next=q->next;e=q->data;//參數帶回被刪數值free(q);return0;}例6-9,P203,約瑟夫環數據使用沒有頭結點的迴圈單鏈表每個結點數據:每個人的序號。當然有指向下一個結點的指針。功能建造迴圈鏈表遊戲的過程列印輸出序列(一邊遊戲一邊列印?將結果保存之後一起列印?)例6-10,P206,學生考試成績處理數據學生資訊採用數組,是結構體數組,每個數組元素有數據:學生姓名,指向成績鏈的指針。學生選修每門課程和成績,一個學生一個單鏈表,鏈表結點數據有:課程名,成績,單鏈表指針。功能見P206圖6-31定義每個模組中函數(函數功能,函數名,參數,返回值)。例:有序數組插入元素/*在第i個元素之前插入元素x。a為整型數組首地址,length為當前數組元素個數,x為元素值。*/intinsertSq(int*a,int&length,inti,intx){ intq; if((i<1)||(i>length+1)) return-1;//i值合理範圍:1~length+1 for(q=length;q>=i;q--) *(a+q)=*(a+q-1); *(a+q)=x; length++; return0;}例:有序數組刪除元素/*刪除第i個元素,指放入參數x。a為整型數組首地址,length為當前數組元素個數。*/intdelSq(int*a,int&length,inti,int&x){ intq; if((i<1)||(i>length)) return-1;//i值合理範圍:1~length x=*(a+i-1); for(q=i;q<length;q++) *(a+q-1)=*(a+q); length--; return0;}數組與單鏈表的優缺點總結數組預知數據多少必須用連續存儲空間支持隨機存取插入刪除操作需要移動大量元素單鏈表不需預知數據量不需連續存儲空間不支持隨機存取插入刪除操作不需移動大量元素不用指針實現單鏈表有些語言沒有提供指針類型七、檔持久化存儲數據外存數據以檔形式組織依組織形式不同,分為兩類:文本檔二進位檔文本檔以字元為單位,每個字元一個位元組,存放ASCII碼例如:00111000001101110011011000110101存放8765有若干文本行,每行以換行符’\n’結束文本檔結束標誌是EOF,它的值為-1二進位檔以二進位形式存儲數據例如:數值8765存放:0010001000111101需要兩個位元組存儲這個數值所以,二進位檔也可以看成位元組序列,稱為位元組流,有了這一特徵,也將檔稱為流式檔檔指針FILE結構:一個記憶體中的FILE結構對應一個磁片檔,FILE結構聲明在stdio.h中。見P211頁定義。使用想檔,先定義檔指針FILE*<指針變數名>;FILE*fp;打開檔打開檔,系統自動創建一個FILE結構,並將提供指向此結構的指針。完成庫函數:FILE*fopen(char*fname,char*mode)FILE*fp;if(fp=fopen(“c:\\file.dat",“r")==NULL)printf(“\n不能打開檔");檔操作模式mode參數的值,見P212表關閉檔打開檔後必須關閉檔,否則可能造成檔指針洩漏或檔數據丟失。完成庫函數:成功返回0,否則為非0值intfclose(FILE*fp)if(fclose(fp))printf(“\n檔關閉有錯誤");檔讀寫打開檔後可對檔進行讀寫操作。庫函數中有若干檔讀寫函數:字元讀寫操作字串讀寫操作數據塊讀寫操作格式化讀寫操作字元讀寫操作intfgetc(FILF*fp)在stdio.h中從fp所指檔的當前位置讀取一個字元,並將檔位置指示器增大;返回值為字元轉換的整數。到達檔尾時返回值為EOFintfputc(intc,FILF*fp)在stdio.h中將字元c寫到fp所指的檔的當前位置,並將檔位置指示器增大;返回值為所寫的字元的值;字元讀寫操作例題:讀取一個文本檔,並將內容顯示。#include<stdio.h>intmain(){ FILE*fp; intch; if((fp=fopen("e:\\a.txt","r"))==NULL){

printf("打不開檔");

return-1;} ch=fgetc(fp); while(ch!=EOF){ putchar(ch); ch=fgetc(fp); } fclose(fp); return0;}字元讀寫操作例題:文本檔拷貝#include<stdio.h>intmain(){ FILE*fp1,*fp2; intch; if((fp1=fopen("e:\\a.txt","r"))==NULL){

printf("打不開舊檔");

return-1;} if((fp2=fopen("e:\\b.txt","w"))==NULL){

printf("打不開新檔");

return-1;} while((ch=fgetc(fp1))!=EOF){ fputc(ch,fp2); } fclose(fp1); fclose(fp2);}字串讀寫操作

char*fgets(char*str,intnum,FILF*fp)在stdio.h中從fp中讀取至多num-1個字元,放入str指向的字元數組,並在最後一個字元位置加上‘\0’,遇到換行符或EOF時讀取也停止;操作成功,返回str,失敗時返回空指針;intfputs(char*str,FILF*fp)在stdio.h中把str所指的字串的內容寫入fp檔流,但不寫‘\0’;操作成功,返回0,失敗時為非0值;字串讀寫操作例題:讀取一個文本檔,並將內容顯示。#include<stdio.h>intmain(){ inti; charlines[1024][80]; FILE*fp; intch; if((fp=fopen("e:\\a.txt","r"))==NULL){

printf("打不開檔");

return-1;} for(i=0;!feof(fp);i++){ fgets(&lines[i][0],80,fp); puts(lines[i]); } fclose(fp); return0;}字串讀寫操作例題:文本檔拷貝#include<stdio.h>intmain(){ inti; charlines[1024][80]; FILE*fp1,*fp2; intch; if((fp1=fopen("e:\\a.txt","r"))==NULL){

printf("打不開舊檔");

return-1;} if((fp2=fopen("e:\\b.txt","w"))==NULL){

printf("打不開新檔");

return-1;} for(i=0;!feof(fp1);i++){ fgets(&lines[i][0],80,fp1); fputs(&lines[i][0],fp2); } fclose(fp1); fclose(fp2);}數據塊讀寫操作intfread(void*buffer,intsize,intcount,FILE*fp)intfwrite(void*buffer,intsize,intcount,FILE*fp)buffer---指向存放位置的指針size---每個讀寫塊的位元組數count---待讀寫的塊數fp---檔指針數據塊讀寫操作例題:從鍵盤輸入學生資訊,寫入二進位檔,再從該檔中讀取學生資訊,顯示在螢幕上。#include<stdio.h>#defineNUM3structinfo{ intNo; charname[16];};intmain(){ inti; infos; FILE*fp; if((fp=fopen("e:\\c.txt","wb"))==NULL){ printf("打不開檔");return-1; } for(i=0;i<NUM;i++){ scanf("%d%s",&s.No,); fwrite(&s,sizeof(info),1,fp); } fclose(fp); if((fp=fopen("e:\\c.txt","rb"))==NULL){ printf("打不開檔");return-1; } while(fread(&s,sizeof(info),1,fp)){ printf("\n%4d%16s",s.No,); } fclose(fp);}格式化讀寫操作intfscanf(FILE*fp,char*format,arg_list)intfprintf(FILE*fp,char*format,arg_list)與scanf和printf類似格式化讀寫操作例題:從鍵盤輸入學生資訊,寫入二進位檔,再從該檔中讀取學生資訊,顯示在螢幕上。#include<stdio.h>#defineNUM3structinfo{ intNo; charname[16];};intmain(){ inti; infos; FILE*fp; if((fp=fopen("e:\\c.txt","w"))==NULL){ printf("打不開檔");return-1; } for(i=0;i<NUM;i++){ scanf("%d%s",&s.No,); fprintf(fp,"\n%4d%16s",s.No,); } fclose(fp); if((fp=fopen("e:\\c.txt","r"))==NULL){ printf("打不開檔");return-1; } while(!feof(fp)){ fscanf(fp,"%d%s",&s.No,); printf("\n%4d%16s",s.No,); } fclose(fp);}八、聯合體與枚舉類型聯合體多個變數共用一個存儲空間位置,這些變數可以是不同的數據類型,聯合體存儲空間大小為多個變數中最大一個變數佔用的空間大小union<聯合體類型名>{<成員列表>}unionuType{inti;//2個位元組charch;//1個位元組}uTypea;a占多大空間?2個位元組a.i占多大空間?2個位元組a.ch占多大空間?1個位元組枚舉類型定義類型:enum<枚舉類型名>{<枚舉值列表>}enumweekday{Sun,Mon,Tue,Wed,Thu,Fri,Sat};枚舉是一個被命名的整型常量的集合。列表中每個枚舉值對應一個序號:0、1、2、3、4、5、6。而不是字串。占整型常量空間枚舉變數值只能是枚舉值列表中列出的值之一枚舉類型使用枚舉變數的好處限制變數取值範圍提高程式的可讀性定義變數:enumweekdayday;操作:day=Wed;第7章C程式實例軟體開發過程:通訊錄管理應用程式1.需求分析2.概要設計3.詳細設計4.測試用例與測試結果5.用戶手冊6.總結1.需求分析1.1功能1.2數據1.3環境1.4介面1.需求分析1.1功能用戶提出的功能創建通訊錄增加一人紀錄刪除指定紀錄根據給定條件查詢記錄顯示通訊錄中的所有記錄將通訊錄資訊寫入檔從檔中讀取通訊錄資訊設計者給出的功能菜單安全管理……1.需求分析1.2數據需要處理數據每個人的通訊資訊:姓名,電話號碼。每本通訊錄中的紀錄條目可能相差很遠。通訊錄數據需要以檔形式長期保存,檔的格式有無特定的要求。用於管理數據要不要菜單記住上次使用時的狀態?密碼資訊的設計?1.需求分析1.3開發環境硬體環境處理器Pentium233MHz或更高頻率的處理器;推薦使用PentiumIII記憶體64MBRAM(最低);128MBRAM(推薦)磁片空間245MB顯示器超級VGA(800x600)或更高解析度,256色軟體環境操作系統MicrosoftWindows2000SP3或更高版本,或者使用WindowsXP或更高版本(推薦)其他1.需求分析1.4介面列出介面的功能給出介面的樣式(圖)需求分析的評審完全清楚了“做什麼”。2.概要設計概要設計的概念與原則模組化:把程式劃分成若干個模組;抽象與逐步求精資訊隱藏:數據的可見範圍模組的獨立性2.概要設計2.1程式結構圖。例:P253模組名字、編號、說明2.概要設計2.2數據結構。例:P2521、主要數據結構:鏈表結點的定義:typedefstructaddress{charname[24]; chartele[24]; structaddress*next;}ADDR;頭指針:head2.概要設計2.3各模組說明。包括:功能,函數名,參數,返回值等。2.3.1顯示菜單2.3.2選擇菜單2.3.3釋放鏈表結點……2.3.10顯示通訊錄資訊2.3.11主函數2.概要設計例:應包括:功能,函數名,參數,返回值等。2.3.3釋放鏈表結點函數:voidfreeRecord(ADDR*head);功能:釋放head鏈表的所有結點參數:head的鏈表的頭指針(帶頭結點)返回值:無2.概要設計2.4介面設計2.4.1外部介面通訊錄管理應用程式:檔存儲的數據:通訊錄數據,管理數據檔格式2.4.2內部介面無3.詳細設計各模組程式流程圖以及局部數據結構說明3.1顯示菜單3.2………3.8將通訊錄資訊寫入檔模組名:voidsaveFile(ADDR*head);右圖取自書P2544.測試用例與測試結果4.1模組測試(可暫無)4.2集成測試……導致錯誤的用例導致正確的用例邊界數據用例…5.用戶手冊應用程式功能的詳細說明;應用程式運行環境的要求;應用程式的安裝與啟動方法;程式的介面、交互方式和操作方法;輸入數據類型、格式和內容限制;在應用程式運行中,用戶需要使用的交互命令名稱、功能和格式的詳細說明。6.總結程式開發中的體會與收穫;開發中遇到的問題與解決情況;自己對自己完成課設情況的評價;對於《高級語言程式設計Ⅲ》與《高級語言程式設計課程設計》兩門課程的意見與建議。附件程式清單期末報告提交裝訂成冊,注意節約;要有目錄,頁碼對應;具體見《高級語言程式設計課程設計指導書》。第3章演算法初步一、解題方法二、演算法舉例---窮舉法三、演算法舉例---遞推與迭代法四、良好的編程風格一、解題方法分析問題,想出策略;自頂向下,逐步求精。例如,編寫一個通訊錄程式通訊錄需要存儲什麼數據?存在什麼地方?程式的功能輸入一個新名字刪除一個名字顯示整個通訊錄搜索一個名字進入、退出程式等……。具體到每一項功能菜單,將這些功能分類別設計用電腦解決問題的步驟分析問題選擇解決方案編寫程式調試程式測試程式數據結構設計演算法設計程式=數據結構+演算法如何組織數據C語言提供了豐富的手段數據結構數據對象:分析所研究問題,提煉出性質相同的數據元素。對象之間的關係通訊錄數據用於管理的數據在此基礎上,想出處理的方法---演算法演算法演算法是指用電腦解決問題的程式或步驟,這些程式或步驟必須是明確和有效的,而且能夠在有限步之內完成。演算法的特徵:確定性邏輯性有窮性

用程式流程圖描述演算法描述演算法的方法有很多程式流程圖:圖形化的描述程式執行過程(圖是工程師的語言)使得思想集中於演算法設計,不受語言細節干擾再依據演算法,用語言編寫程式程式流程圖的圖形符號:P60開始結束顯示菜單獲取用戶選擇處理用戶選擇用戶選擇了結束NY再繼續細化,畫子流程圖主程序輸入新名字刪除名字顯示整個通訊錄搜索一個名字進入程式…………例:求一元二次方程ax2+bx+c=0的解#include<stdio.h>#include<math.h>main(){ inta,b,c,t; printf("Inputa,b,c:"); scanf("%d%d%d",&a,&b,&c); t=b*b-4*a*c; if(t<0) printf("Nosolution\n"); elseif(t==0) printf("X=%lf\n",-b/(2.0*a)); else{ doublet0; t0=sqrt((double)t); printf("X1=%lf,X2=%lf\n", (-b+t0)/(2*a),(-b-t0)/(2*a));} }二、演算法舉例---窮舉法列出所有可能情況,逐個排查,從中找出符合條件的解。關鍵是明確問題所有可能性,注意可能情況是有限的。用什麼基本控制結構?優點?缺點?迴圈時間效率可能不高問題分析利用素數的定義來判別。對於給定整數x,用2~x-1之間的每個整數試除,若都不能整除則是素數,否則不是素數。一次試除成功(不能整除),並不能說明x是素數,只有所有試除都成功,才能斷定x是素數;但一次試除失敗(能整除),則可斷定x不是素數例:判斷給定整數是否是素數解決方案數據結構設計整型變數存儲素數

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论