本文目錄一覽:
- 1、什麼是C語言程序設計?
- 2、C語言課程設計報告要求
- 3、求一份C語言課程設計報告要求包括:系統需求分析,總體設計,詳細設計,程序調試分析。
- 4、《C語言程序設計》項目設計
- 5、C語言程序設計中應注意哪些問題
- 6、C語言程序設計加註釋完成下列要求
什麼是C語言程序設計?
什麼是C語言?C語言的簡介。
C語言是一種計算機程序設計語言,它既具有高級語言的特點,又具有彙編語言的特點。
它可以作為工作系統設計語言,編寫系統應用程序,也可以作為應用程序設計語言,編寫不依賴計算機硬體的應用程序。
因此,它的應用範圍廣泛,不僅僅是在軟體開發上,而且各類科研都需要用到C語言,具體應用比如單片機以及嵌入式系統開發。
語言特點:C是中級語言/C是結構式語言/C語言功能齊全/C語言適用範圍大/簡潔緊湊、靈活方便/運算符豐富/數據類型豐富/C是結構式語言/語法限制不太嚴格,程序設計自由度大/適用範圍大,可移植性好。
C語言課程設計報告要求
一 、 設計題目
萬年曆的設計
二 、設計要求
1、能夠顯示星期;
2、能夠顯示年月日;
3、能夠修改;
4、當系統時間變動時,能自動跳到相應的時間。
三 、 設計目的
1. 通過本項課程設計,可以培養獨立思考、 綜合運用所學有關相應知識的能力,能更好的鞏固《C語言程序設計》課程學習的內容,掌握 工程軟體設計的基本方法,強化上機動手編程能力,闖過理論與實踐相結合的難關!更加了解了c語言的好處和其可用性!同時增加了同學之間的團隊合作精神!更加也體會到以後在工作中團隊合作的重要性和必要性!
2. 通過C語言課程設計,使學生了解高級程序設計語言的結構,掌握基本的程序設計過程和技巧,掌握基本的分析問題和利用計算機求解問題的能力,具備初步的高級語言程序設計能力。為後續各門計算機課程的學習和畢業設計打下堅實基礎。
四 、設計思想及過程
【一】由於萬年曆具有以下特點:
1。平年365天(52周+1天),閏年366天(52周+2天)。平年2月28天,閏年2月29天。
由於公元1月1日設為星期六,故3月1日為星期三。 ——注意這個「三」
為使演算法達到最簡,故本演算法以「星期」為計算單位。且選3月1日為基月。
2。每400年整一閏,或每4年且不為百年的一閏。(原因:地球繞太陽一周的時間是365天5小時46秒,為了使一年的天數為整數,將一年的天數定為365天,餘下的時間積累起來,四年就是23小時15分4秒,將近一天,把這一天加在某年的二月而成29天,該年稱為閏年,其它年稱為平年。但四年加一天又多用了44分56秒,這個數積滿400年為三天。因此400年中只能有97個閏年,所以凡能被400整除,或不能被100整除但能被4整除的年份為閏年。)
所以百年%4=0閏或(年%4=0並且年0)閏。
3。每 4年(3個平年+1個閏年)共208周+5天 ——注意這個「5天」
每百年共100*(208周+5天)-1天=5217周+5天 ——注意這個「5天」(整百年暫設為平年)
每400年共4*(5217周+5天)+1天(整400年閏)=20871周+0天——注意這個「0天」和
「1天」(4個整百年只有一個閏年)
即400年一輪迴!(原來萬年曆400年前是一家)
【二】根據萬年曆以上特點進行編寫:
首先對萬年曆年、月、日進行編寫,編寫程序先定義每月的天數為28天,如月份為1、3、5、7、8、10、12就定義天數為31天反之如果月份為4、6、9、11就輸出天數為30天,由上可見2月份為28天但是如果為閏年就有29天就要定義另一個函數#define Year(x) (x%4==0x%100!=0||x%400==0) ? 1:0當為閏年時可得1加上該程序便可得到每月的天數。 具體程序見(五、萬年曆程序)
再對其中的星期進行編寫:由於公元1月1日設為星期六,故3月1日為星期三,可以用萬年3月1日星期演算法(特別是那個三)
由於其公式為:
某年3月1日星期幾=(3天+百年%4*5天+年/4*5天+年%4+月星期表+日-1天)%7
某年3月1日星期幾=(百年%4*5天+年/4*5天+年%4+月星期表+日+2天)%7
或 某年3月1日星期幾=(百年%4*5天+年+年/4+月星期表+日+2天)%7
閏4百年3月1日星期演算法(百年%4=0)
其公式為:
某年3月1日星期幾=(年+年/4+月星期表+日+2天)%7
例:0000年3月1日星期幾=(0+0/4+0+1+2)%7=3%7=星期三
1600年3月1日星期幾=(0+0/4+0+1+2)%7=3%7=星期三
2000年3月1日星期幾=(0+0/4+0+1+2)%7=3%7=星期三
2001年3月1日星期幾=(1+1/4+0+1+2)%7=4%7=星期四
2004年3月1日星期幾=(4+4/4+0+1+2)%7=8%7=星期一
2008年3月1日星期幾=(8+8/4+0+1+2)%7=13%7=星期六
2042年3月1日星期幾=(42+42/4+0+1+2)%7=55%7=星期六
平4百年3月1日星期演算法(百年%40)
其公式為:
某年3月1日星期幾=(百年%4*5天+年+年/4+月星期表+日+2天)%7
例:1700年3月1日星期幾=(17%4*5+0+0/4+0+1+2)%7=8%7=星期一(注意:1700年是平年)
1800年3月1日星期幾=(18%4*5+0+0/4+0+1+2)%7=13%7=星期六(注意:1800年是平年)
1900年3月1日星期幾=(19%4*5+0+0/4+0+1+2)%7=18%7=星期四(注意:1900年是平年)
1901年3月1日星期幾=(19%4*5+1+1/3+0+1+2)%7=19%7=星期五
1918年3月1日星期幾=(19%4*5+18+18/4+0+1+2)%7=(15+22+3)%7=40%7=星期五
1958年3月1日星期幾=(19%4*5+58/4*5+58%4+3)%7=(15+70+2+3)%7=90%7=星期六
1988年3月1日星期幾=(19%4*5+88/4*5+88%4+3)%7=(15+110+0+3)%7=128%7=星期二
1999年3月1日星期幾=(19%4*5+99/4*5+99%4+3)%7=(15+120+3+3)%7=141%7=星期一
2100年3月1日星期幾=(21%4*5+0/4*5+0%4+3)%7=(5+0+0+3)%7=8%7=星期一(注意:2100年是平年)
2101年3月1日星期幾=(21%4*5+1/4*5+1%4+3)%7=(5+0+1+3)%7=9%7=星期二
2102年3月1日星期幾=(21%4*5+2/4*5+2%4+3)%7=(5+0+2+3)%7=10%7=星期三
2103年3月1日星期幾=(21%4*5+3/4*5+3%4+3)%7=(5+0+3+3)%7=11%7=星期四
2104年3月1日星期幾=(21%4*5+4/4*5+4%4+3)%7=(5+1+0+3)%7=9%7=星期二(注意:2104年是閏年)
9999年3月1日星期幾=(99%4*5+99/4*5+99%4+3)%7=(120+15+3+3)%7=141%7=星期一
註:按400年一輪迴!(400年前是一家)的說法
1600年,2000年是一樣的;
1700年,2100年是一樣的;
1800年,2200年是一樣的;
1900年,2300年是一樣的。
其中萬年某日星期演算法
其公式為:
某日星期幾=(百年%4*5天+年+年/4+月星期表+日+2天)%7
通同星期偏差表
閏年 1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月
天數 31 29 31 30 31 30 31 31 30 31 30 31
星期 3 6 0 3 5 1 3 6 2 4 0 2
平年 1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月
天數 31 28 31 30 31 30 31 31 30 31 30 31
星期 4 0 0 3 5 1 3 6 2 4 0 2
為對以上的萬年曆星期的演算法是正確的對其進行了以下的計算:
⒈對於二十世紀任意日期可以用公式某日星期幾=(百年%4*5天+年+年/4+平年月星期表+日+2天)%7=(19%4*5天+年+年/4+平年月星期表+日+2天)%7=(15天+年+年/4+平年月星期表+日+2天)%7以下就是根據上面對其進行的計算:
1900年元旦 1日=(0/4*5+0%4+1+3)%7=(0+0+4)%7=4
1月表=4(平年) 故 4+4=1 即1900年元旦是星期一
1949年國慶 1日=(49/4*5+49%4+1+3)%7=(60+1+4)%7=2
10月表=4(平年) 故 4+2=6 即1949年國慶是星期六
1999年12月31日 31日=(99/4*5+99%4+31+3)%7=(120+3+34)%7=3
12月表=2(平年) 故 2+3=5 即1999年12月31日是星期五
⒉對於二十一世紀新前年蟲演算法(20%4*5=0)可以用公式:某日星期幾=(百年%4*5天+年+年/4+閏年月星期表+日+2天)%7 =(20%4*5天+年+年/4+閏年月星期表+日+2天)%7以下就是根據上面對其進行的計算:
2000年元旦 1日=(0+0/4+1+2)%7=(0+0+1+2)%7=3
1月表=3(閏年) 故 3+3-6 即2027年元旦是星期六
2018年春節 16日=(18+18/4+16+2)%7=(18+4+16+2)%7=5
2月表=0(平年) 故 0+5=5 即2018年春節是星期五
2099年12月31日 31日=(99/4*5+99%4+31+2)%7=(120+3+33)%7=2
12月表=2(平年) 故 2+2=4 即2099年12月31日是星期四
對於上面的分析以及公式的推論和計算證明可以對萬年曆中的星期進行了編寫具體編寫程序見(五 、萬年曆程序)中。
五 、萬年曆源程序
#include”stdio.h”
#include”dos.h”
#include”conio.h”
#include”stdlib.h”
#define Year(x) (x%4==0x%100!=0||x%400==0) ? 1:0 /*判斷閏年*/
int numofMonth(int y,int m){
int day,t=28;
if(m==1||m==3||m==5||m==7||m==8||m==10||m==12)
day=31; /*定義以上月份為31天*/
else if(m==4||m==6||m==9||m==11)
day=30; /*定義以上月份為30天*/
else{t+=Year(y);
day=t;} /*閏年二月29天,平年28天*/
return day;}
int numofYear(int y){
int t=365; /*平年365天*/
t+=Year(y);/*閏年366天*/
return t;}
int numofbeforeDays(int y,int m,int d){
int sum=d,i;
for(i=1;im;i++)
sum+=numofMonth(y,i);
return sum;}
int numofafterDays(int y,int m,int d){
int sum=0,i;
for(i=m;i=12;i++)
sum+=numofMonth(y,i);
sum-=d;
return sum;}
int isDay(int y,int m,int d){
int year=1900,month=1,week=1,i; /*定義萬年曆是從1900年開始*/
long sum=0;
for(i=year;iy;i++)
sum+=numofYear(i);
for(i=1;im;i++)
sum+=numofMonth(y,i);
/* ++sum;*/
i=sum%7;
week=(week+i)%7;
return week;}
void empty(int n){
int i;
for(i=0;in;i++)
printf(“%*c”,6,’ ‘);}
void OutPutCalender(int y,int m,int d)/*計算x年x月x是星期幾*/{
int week,i,num,t;
week=isDay(y,m,1);
printf(“%6d/%02d/%02d\n”,y,m,d);
printf(“%6s%6s%6s%6s%6s%6s%6s\n”,”Sun”,”Mon”,”Tue”,”Wed”,”Thu”,”Fri”,”Sat”);
empty(week);
num=numofMonth(y,m);
for(i=1;i=num;i++){
printf(“%6d”,i);
t=(week+i)%7;
if(t==0)
printf(“\n”);} /*游標移到下一行*/
printf(“\n”);}
long numBTDays(int y1,int m1,int d1,int y2,int m2,int d2)/*定義兩個不同日期*/{
int i;
long sum=0;
for(i=y1+1;iy2;i++)
sum+=numofYear(i);
if(y1==y2){ sum-=d1;
for(i=m1;im2;i++)
sum+=numofMonth(y1,i);
sum+=d2;}
else{sum+=numofafterDays(y1,m1,d1);
sum+=numofbeforeDays(y2,m2,d2);}
return sum;}
int Select_mean(){
int sm;
printf(“1. OutPut Calender\n”); /*輸出當前月份的日曆*/
printf(“2. Help\n”); /*幫助*/
printf(“0. Quit\n”); /*退出*/
printf(“Please enter choose(0–2):”); /*從0-2中選擇*/
do
scanf(“%d”,sm); /*輸入sm*/
while(sm0||sm3);
return sm;}
void Help()/*輸出幫助欄的內容*/{
printf(” 1. OutPut Calender\n”);
printf(” 2. System Help\n”);
printf(” 0. Quit\n”);
printf(“Page Up: Up year\n”); /*上一年*/
printf(“Page Down: next year\n”); /*下一年*/
printf(” — : next month\n”); /*上一月*/
printf(” — : Up month\n”);/*下一月*/}
main(){
int year=2006,year1=2006,month,day,y1,m1,d1,y2,m2,d2,c,t; /*定義運行後的日期是2006年*/
int inkeySCAN,inkey; /*輸入鍵盤操作信息*/
union REGS inregs,outregs;
inregs.h.ah=0x2a;
intdos(inregs,outregs);
/* year=outregs.xcx; */
month=outregs.h.dh;
day=outregs.h.dl;
year1=year;
printf(“%d/%02d/%02d\n”,year,month,day);
while(1)/*當選擇為1時,執行以下語句*/{
switch(Select_mean()){
case 1:
OutPutCalender(year,month,day);
while(1){
inkey=bioskey(0);
inkeySCAN=(inkey0xFF00)8;
if(inkeySCAN==77){
if(month==12){month=1;year1++;
OutPutCalender(year1,month,day);/*輸出日曆*/}
else{month++;
OutPutCalender(year1,month,day);
}}
if(inkeySCAN==75){
if(month==1){month=12;year1–;
OutPutCalender(year1,month,day);}
else{month–;OutPutCalender(year1,month,day);}}
if(inkeySCAN==73){
if(year1==1900) year1=year;
else{year1–;OutPutCalender(year1,month,day);}}
if(inkeySCAN==81){
year1++;OutPutCalender(year1,month,day);}
if(inkeySCAN==28)break;}
break; /*終止循環*/
case 2:
Help();
break;
case 0:
exit(0);
default:
printf(“Enter ERROR!\n”);
break;} }
}
六 運行過程
1.雙擊TC
1. 當對上面的程序進行了調試後運行會出現下面所示:
第一行所顯示的就是系統時間!滿足了第一條要求「顯示年、月、日」。
而當改變系統時間後!再運行該程序上面的日期也隨系統時間改變,所以滿足第四條「當系統時間變動時,能自動跳到相應的時間。」
2. 在游標處按下「1」後回車,將會顯示:
以上的顯示也證明了條件的第2條可以「顯示星期!」
3. 在游標處按下「2」後回車,將會顯示:
按著幫助所講進行了運行可知:按「 Page Up 」鍵其下面接著會顯示上一年該月的萬年曆,按「 Page Down 」鍵其下面會接著顯示下一年該月的萬年曆;按「 ← 」鍵下面將會接著顯示當年上一個月的萬年曆,按「 → 」鍵將會接著在下面顯示去下一個月的萬年曆。
4.
由上所顯示鍵入「0」後將會退去該程序。
由以上運行的結果可知該c語言所設計的萬年曆滿足設計要求!
七、在C語言編程中常見錯誤
C語言的最大特點是:功能強、使用方便靈活。C編譯的程序對語法檢查並不象其它高級語言那麼嚴格,這就給我們留下「靈活的餘地」,但還是由於這個靈活給程序的調試帶來了許多不便,尤其對我們這些初學C語言的人來說,經常會出一些連自己都不知道錯在哪裡的錯誤。看著有錯的程序,不知該如何改起,我通過這次編程,也積累了一些C編程時常犯的錯誤:
1. 書寫標識符時,忽略了大小寫字母的區別。
編譯程序把a和A認為是兩個不同的變數名,而顯示出錯信息。C語言認為大寫字母和小寫字母是兩個不同的字元。習慣上,符號常量名用大寫,變數名用小寫表示,以增加可讀性。
2.忽略了變數的類型,進行了不合法的運算。
%是求余運算,得到a/b的整餘數。整型變數a和b可以進行求余運算,而實型變數則不允許進行「求余」運算。
3.將字元常量與字元串常量混淆。
混淆了字元常量與字元串常量,字元常量是由一對單引號括起來的單個字元,字元串常量是一對雙引號括起來的字元序列。C規定以「\」作字元串結束標誌,它是由系統自動加上的,所以字元串「a」實際上包含兩個字元:『a’和『\’,而把它賦給一個字元變數是不行的。
4.忽略了「=」與「==」的區別。
在C語言中,「=」是賦值運算符,「==」是關係運算符。如:
if (a==3) a=b;
前者是進行比較,a是否和3相等,後者表示如果a和3相等,把b值賦給a。由於習慣問題,初學者往往會犯這樣的錯誤。
5.忘記加分號。
分號是C語句中不可缺少的一部分,語句末尾必須有分號。
a=1 b=2
編譯時,編譯程序在「a=1」後面沒發現分號,就把下一行「b=2」也作為上一行語句的一部分,這就會出現語法錯誤。改錯時,有時在被指出有錯的一行中未發現錯誤,就需要看一下上一行是否漏掉了分號。
{ z=x+y;
t=z/100;
printf(“%f”,t);
}
對於複合語句來說,最後一個語句中最後的分號不能忽略不寫(這是和PASCAL不同的)。
6.多加分號。
對於一個複合語句,如:
{ z=x+y;
t=z/100;
printf(“%f”,t);
};
複合語句的花括弧後不應再加分號,否則將會畫蛇添足。
又如:
if (a%3==0);
I++;
本是如果3整除a,則I加1。但由於if (a%3==0)後多加了分號,則if語句到此結束,程序將執行I++語句,不論3是否整除a,I都將自動加1。
再如:
for (I=0;I5;I++);
{scanf(“%d”,x);
printf(“%d”,x);}
本意是先後輸入5個數,每輸入一個數後再將它輸出。由於for()後多加了一個分號,使循環體變為空語句,此時只能輸入一個數並輸出它。
7.輸入變數時忘記加地址運算符「」。
int a,b;
scanf(“%d%d”,a,b);
這是不合法的。Scanf函數的作用是:按照a、b在內存的地址將a、b的值存進去。「a」指a在內存中的地址。
8.輸入數據的方式與要求不符。scanf(“%d%d”,a,b);輸入時,不能用逗號作兩個數據間的分隔符,如下面輸入不合法:
3,4
輸入數據時,在兩個數據之間以一個或多個空格間隔,也可用回車鍵,跳格鍵tab。
scanf(“%d,%d”,a,b);C規定:如果在「格式控制」字元串中除了格式說明以外還有其它字元,則在輸入數據時應輸入與這些字元相同的字元。下面輸入是合法的:
3,4
此時不用逗號而用空格或其它字元是不對的。
3 4 3:4
又如:
scanf(“a=%d,b=%d”,a,b);
輸入應如以下形式:
a=3,b=4
9.輸入字元的格式與要求不一致。
在用「%c」格式輸入字元時,「空格字元」和「轉義字元」都作為有效字元輸入。
scanf(“%c%c%c”,c1,c2,c3);
如輸入a b c
字元「a」送給c1,字元「 」送給c2,字元「b」送給c3,因為%c只要求讀入一個字元,後面不需要用空格作為兩個字元的間隔。
10.輸入輸出的數據類型與所用格式說明符不一致。
例如,a已定義為整型,b定義為實型
a=3;b=4.5;
printf(“%f%d\n”,a,b);
語法錯
邏輯錯 運行錯
0.忘記定義變數:
main()
{x=3;y=6;
printf(「%d\n」,x+y);
11.C語言的變數一定要先定義才能使用;
12.輸入輸出的數據的類型與所用格式說明符不一致
int a=3;float b=4.5;printf(「%f%d\n」,a,b);
它們並不是按照賦值的規則進行轉換(如把4.5轉換為4),而是將數據在存儲單元中的形式按格式符的要求組織輸出(如b佔4個位元組,只把最後兩個位元組的數據按%d,作為整數輸出)
13.未注意int型數據的數值範圍
int型數據的數值範圍(-32768~32768)
int num=89101;
printf(「%d」,num);
會將超過低16位的數截去從而得到23563
注意:定義了long型,而在輸出時仍用」%d」說明符,仍會出現以上錯誤
14.輸入變數時忘記使用地址符
scanf(「%d%d」,a,b);
15.輸入時數據的組織與要求不符
對scanf函數中格式字元串中除了格式說明符外,對其他字元必須按原樣輸入
16.誤把」=「作為」等於」比較符
「=「為附值運算符
「==「為比較運算符
17.語句後面漏分號
{
t=a;
a=b;
b=t
}
它是pascal的語法
18.不該加分號的地方加了分號
if(ab);
printf(「a is larger than b\n」);
for(i=0;i10;i++);
{
scanf(「%d」,x);
printf(「%d\n」,x*x);
}
19.對應該有花括弧的複合語句,忘記加花括弧
sum=0;
i=1;
while(i=100)
sum=sum+1;
i++;
20.括弧不配對
while((c=getchar()!=『#』)
putchar(c);
11.在用標識時,忘記了大寫字母和小寫字母的區別
{
int a,b,c;
a=2;
b=3;
C=A+B;
printf(「%d+%d=%D」,A,B,C);
}
12.引用數組元素時誤用發圓括弧
{
int i,a(10);
for(i=0;i10;i++)
scanf(「%d」,a(i));
}
13.在定義數組時,將定義的」元素個數」誤認為是」可使用的最大下標值
{
int a[10]={1,2,3,4,5,6,7,8,9,10};
int i;
for(i=1;i=10;i++)
printf(「%d」,a[i]);
}
14.對二維或多維數組的定義和引用的方法不對
{
int a[5,4];
…
printf(「%d」,a[1+2,2+2]);
…
}
15.誤以為數組名代表數組中全部元素
{int a[4]={1,2,3,4};
printf(「%d%d%d%d」,a);
}
16.混淆字元數組與字元指針的區別
main()
{
char str[40];
str=「Computer and c」;
printf(「%s\n」,str);
}
17.在引用指針變數之前沒有對它賦予確定的值
{
char *p;
scanf(「%s」,p);
}
{
char *p,c[20];
p=c;
scanf(「%s」,p);
}
18.switch語句的各分支中漏寫 break語句
混淆字元和字元串的表示形式
…
char sex;
sex=「M」;
…
19.使用自加(++)和自減(–)運算符時出的錯誤
{
int *p,a[5]={1,3,5,7,9};
p=a;
printf(「%d」,*p++);
}
注意於*(++p)的區別;
20.所調用的函數在調用語句之後才定義,而又在調用前未加說明
main()
{float x,y,z;
x=3.5;y=-7.6;
z=max(x,y);
printf(「%f」,z);
}
編譯時不給出出錯信息,但運行結果將與原意不符。這種錯誤尤其需要注意。
八、心得體會
1. 目前流行的計算機日曆程序,比較典型的是Windows各版本中的日曆程序以及基礎於該程序所開發的各種應用程序中的日曆程序。然而,這些程序都千篇一律的局限在一個很短的時間範圍內。(Windows各個版本一般都局限在1980年至2099年這一範圍內),但是,在很多情況下,特別是在眾多的科學研究領域中,一個時間跨度較大的日曆程序是很有參考價值的。C程序設計語言充分發揮了其自身無與倫比的優越性,用極短的程序文本填補了這一領域的空白,同時用鐵的事實強有力的告訴世人:C程序設計語言作為計算機語言家族的新生事物,其發展前景是極為廣闊的。
2. 經過上一個學期對《C程序設計》的學習,我們學習了理論知識,了解了C語言程序設計的思想,這些知識都為我們的下一步學習打下了堅實的基礎。通過課程設計,一方面是為了檢查我們一個學期來我們學習的成果,另一方面也是為了讓我們進一步的掌握和運用它,同時也讓我們認清自己的不足之處和薄弱環節,加以彌補和加強。
3. 通過對c語言萬年曆的設計進一步的鞏固了用c語言編寫程序,並且有利於更好的掌握c語言!
4. 在萬年曆的編寫過程中也體會到了做事情一頂要細心、認真。更加知道了要掌握好基礎知識。還有體會到了成功的感覺!在萬年曆的設計過程中更加體會到了團隊合作的重要性,「一個諸葛亮比不上三個臭皮匠。」知道了只有團隊合作才會更好的完成設計!也體會到以後在工作中團隊合作的必要性和重要性!
5. 通過本項課程設計也培養了我獨立思考、 綜合運用所學有關相應知識的能力,掌握 工程軟體設計的基本方法,強化上機動手編程能力,闖過理論與實踐相結合的難關!
6. 由於C語言是近年在國內外得到迅速推廣應用的一種語言。C語言功能豐富,表達能力強,使用靈活方便,應用面廣,目標程序效率高,可移植性好,既具有高級語言的優點,又具有低級語言的許多特點。通過這次的c語言程序設計更加了解了c語言的好處和其可用性!
7. 在這次課程設計中也知道了自己的動手能力不強有待進一部的提高!在設計過程中不能夠把書本上的知識與實踐相結合,這也就增加了設計不好該程序的想法!在設計過程中的一次次設計錯誤增加了我放棄的想法!不過經過大家的努力終於完成了課程設計!完成該程序後想起自己以前的每一次對自己失去信心,就覺得並不是在知識掌握上打敗了,而是自己對自己缺乏信心!只要自己對自己不失去信心相信就可以完成那些以前認為完成不了的事情!也讓我懂得了要想成功首先就必須有很強的自信心!懂得了自己以後要在做任何事情時都要自信!當自己都不相信自己能夠成功時還可能會獲得成功嗎?
8. 在C語言程序設計的過程中也知道了自己在以前的學習中有很大的不足導致在設計過程中出現了很多的問題,有些地方看不懂也不知道怎麼去設計,但是在設計過程中也學習了很多,掌握了自己以前沒有學好的知識,雖然一時可以掌握完以前沒有學好的知識,不過也給自己敲響了警鐘,在學習中不可以伏於表面,要想學好每一門課程都要踏踏實實,做什麼都不是給別人看的!都是要更好的掌握該門知識,提高自己的自身的修養,提高自己的能力!為以後的工作打下良好的知識基礎和技能基礎!
九、參考文獻
⒈譚浩強編著.C程序設計第二版〔M〕.北京:清華大學出版社,1999
⒉陳朔鷹,陳英編著.C語言趣味程序百例精解〔M〕.北京:北京理工大學出版社,1994
⒊電腦知識與技術學術交流版〔J〕2005.2 (備註:來自網路資源)
⒋Herbert Schildit著. 戴健鵬譯. C語言大全 (第二版)〔M〕.北京:電子工業出版社,1994
⒌譚浩強,張基溫,唐永炎編著. C語言程序設計教程.〔M〕北京: 高等教育出版社,1992
⒍秦友淑,曹化工編著. C語言程序設計教程. 〔M〕武漢:華中理工大學出版社,1996
⒎曹衍龍,林瑞仲,徐慧 編著.C語言實例解析精粹 〔M〕北京:人民郵電出版社,2005.3
⒏黃明等編著.21世紀進階輔導C語言程序設計. 〔M〕大連理工大學出版
求一份C語言課程設計報告要求包括:系統需求分析,總體設計,詳細設計,程序調試分析。
C語言課程設計任務書
一、題目: 學生成績管理
二、目的與要求
1. 目的:
(1)基本掌握面向過程程序設計的基本思路和方法;
(2)達到熟練掌握C語言的基本知識和技能;
(3)能夠利用所學的基本知識和技能,解決簡單的程序設計問題
2. 要求
基本要求:
1. 要求利用C語言面向過程的編程思想來完成系統的設計;
2. 突出C語言的函數特徵,以多個函數實現每一個子功能;
3. 畫出功能模塊圖;
4. 進行簡單界面設計,能夠實現友好的交互;
5. 具有清晰的程序流程圖和數據結構的詳細定義;
6. 熟練掌握C語言對文件的各種操作。
創新要求:
在基本要求達到後,可進行創新設計,如系統用戶功能控制,對管理員級和一般級別的用戶系統功能操作不同
三、信息描述
輸入一個班10個學生的學號和每個學生考試三門功課(數學、英語、計算機基礎)的成績。編程計算出每個學生的總分和平均分,並按學生成績優劣排序,最後列印一張按高分到低分名次排序的成績單。要求:
1)排序用一個函數實現。
2)列印的成績單表項包括:序號,學號、數學、英語、計算機、總分、平均分。
3)按實驗報告電子模板格式填寫實驗內容。
四、功能描述
1. 學生基本信息及成績所選科目成績的錄入。
2. 基本信息的查詢(分系、班級;分科目)與修改。
3. 對每系或每班各科成績進行分析(即求單科平均成績、及格率和優秀率);
4. 對所開課程的成績分析(求其平均成績,最高分和最低分);
5. 對學生考試成績進行排名(單科按系別或班級進行排名,對每一個班級,同一學期學生總體成績進行排名,並顯示各科成績信息)
五、解決方案
1. 分析程序的功能要求,劃分程序功能模塊。
2. 畫出系統流程圖。
3. 代碼的編寫。定義數據結構和各個功能子函數。
4. 程序的功能調試。
5. 完成系統總結報告以及使用說明書
六、進度安排
此次課程設計時間為兩周,分四個階段完成:
1. 分析設計階段。指導教師應積極引導學生自主學習和鑽研問題,明確設計要求,找出實現方法,按照需求分析、總體設計、詳細設計這幾個步驟進行。
2. 編碼調試階段:根據設計分析方案編寫C代碼,然後調試該代碼,實現課題要求的功能。
3. 總結報告階段:總結設計工作,寫出課程設計說明書,要求學生寫出需求分析、總體設計、詳細設計、編碼、測試的步驟和內容。
4. 考核階段。
#include stdio.h
#include stdlib.h
#define STU_NUM 10 /*宏定義學生的數量*/
struct student /*定義一個結構體用來存放學生學號、三門課成績、總分及平均成績*/
{
char stu_id[20]; /*學生學號;*/
float score[3]; /*三門課成績;*/
float total; /*總成績;*/
float aver; /*平均成績;*/
};
/*排序用一個函數來實現*/
void SortScore(student *stu,int n)
{
student stud;
for(int i = 0; i n-1; i++)
for(int j = i+1 ; j n; j++)
{
if(stu[i].total stu[j].total)
{
stud = stu[i];
stu[i] = stu[j];
stu[j] = stud;
}
}
}
int main( )
{
student stu[STU_NUM]; /*創建結構體數組中有10個元素,分別用來保存這10個人的相關信息。*/
/*輸入這十個學生的相關信息*/
for(int i = 0; iSTU_NUM; i++)
{
printf(“請輸入第%d個學生的學號:”,i+1);
scanf(“%s”,stu[i].stu_id);
printf(“輸入第%d個學生的數學成績:”,i+1);
scanf(“%f”,stu[i].score[0]);
printf(“輸入第%d個學生的英語成績:”,i+1);
scanf(“%f”,stu[i].score[1]);
printf(“輸入第%d個學生的計算機成績:”,i+1);
scanf(“%f”,stu[i].score[2]);
stu[i].total = stu[i].score[0]+stu[i].score[1]+stu[i].score[2];
stu[i].aver = stu[i].total/3;
}
printf(“\n”);
SortScore(stu,STU_NUM);/*調用排序函數*/
/*輸出排序後的各學生的成績*/
for(i = 0 ; i STU_NUM; i++)
{
printf(“序號: %d\t”,i);
printf(“學號:%s\t”,stu[i].stu_id);
printf(“數學:%f\t”,stu[i].score[0]);
printf(“英語:%f\t”,stu[i].score[1]);
printf(“計算機:%f\t”,stu[i].score[2]);
printf(“平均成績:%f\t”,stu[i].aver);
printf(“總分:%f\t”,stu[i].total);
printf(“\n\n”);
}
return 0;
}
註:(源程序中主要標識符含義說明)
#define STU_NUM 10 /*宏定義學生的數量*/
struct student /*定義一個結構體用來存放學生學號、三門課成績、總分及平均成績*/
{
char stu_id[20]; /*學生學號;*/
float score[3]; /*三門課成績;*/
float total; /*總成績;*/
float aver; /*平均成績;*/
}
實驗結果:
輸入 :(只輸入後面的數字,前面的文字是自己產生的)。
請輸入第1個學生的學號:001
輸入第1個學生的數學成績:1
輸入第1個學生的英語成績:1
輸入第1個學生的計算機成績:1
請輸入第2個學生的學號:002
輸入第2個學生的數學成績:2
輸入第2個學生的英語成績:2
輸入第2個學生的計算機成績:2
請輸入第3個學生的學號:003
輸入第3個學生的數學成績:3
輸入第3個學生的英語成績:3
輸入第3個學生的計算機成績:3
請輸入第4個學生的學號:004
輸入第4個學生的數學成績:4
輸入第4個學生的英語成績:4
輸入第4個學生的計算機成績:4
請輸入第5個學生的學號:005
輸入第5個學生的數學成績:5
輸入第5個學生的英語成績:5
輸入第5個學生的計算機成績:5
請輸入第6個學生的學號:006
輸入第6個學生的數學成績:6
輸入第6個學生的英語成績:6
輸入第6個學生的計算機成績:6
請輸入第7個學生的學號:007
輸入第7個學生的數學成績:7
輸入第7個學生的英語成績:7
輸入第7個學生的計算機成績:7
請輸入第8個學生的學號:008
輸入第8個學生的數學成績:8
輸入第8個學生的英語成績:8
輸入第8個學生的計算機成績:8
請輸入第9個學生的學號:009
輸入第9個學生的數學成績:9
輸入第9個學生的英語成績:9
輸入第9個學生的計算機成績:9
請輸入第10個學生的學號:010
輸入第10個學生的數學成績:10
輸入第10個學生的英語成績:10
輸入第10個學生的計算機成績:10
輸出:
序號: 0 學號:010 數學:10.000000 英語:10.000000 計算機:10.000000
平均成績:10.000000 總分:30.000000
序號: 1 學號:009 數學:9.000000 英語:9.000000 計算機:9.000000
平均成績:9.000000 總分:27.000000
序號: 2 學號:008 數學:8.000000 英語:8.000000 計算機:8.000000
平均成績:8.000000 總分:24.000000
序號: 3 學號:007 數學:7.000000 英語:7.000000 計算機:7.000000
平均成績:7.000000 總分:21.000000
序號: 4 學號:006 數學:6.000000 英語:6.000000 計算機:6.000000
平均成績:6.000000 總分:18.000000
序號: 5 學號:005 數學:5.000000 英語:5.000000 計算機:5.000000
平均成績:5.000000 總分:15.000000
序號: 6 學號:004 數學:4.000000 英語:4.000000 計算機:4.000000
平均成績:4.000000 總分:12.000000
序號: 7 學號:003 數學:3.000000 英語:3.000000 計算機:3.000000
平均成績:3.000000 總分:9.000000
序號: 8 學號:002 數學:2.000000 英語:2.000000 計算機:2.000000
平均成績:2.000000 總分:6.000000
序號: 9 學號:001 數學:1.000000 英語:1.000000 計算機:1.000000
平均成績:1.000000 總分:3.000000
七、撰寫課程設計報告或課程設計總結
課程設計報告要求:
總結報告包括需求分析、總體設計、詳細設計、編碼(詳細寫出編程步驟)、測試的步驟和內容、課程設計總結、參考資料等,不符合以上要求者,則本次設計以不及格記。
C語言常見錯誤
書寫標識符時,忽略了大小寫字母的區別
main()
{
int a=5;
printf(“%d”,A);
}
編譯程序把a和A認為是兩個不同的變數名,而顯示出錯信息。C認為大寫字母和小寫字母是兩個不同的字元。習慣上,符號常量名用大寫,變數名用小寫表示,以增加可讀性。
2.忽略了變數的類型,進行了不合法的運算。
main()
{
float a,b;
printf(“%d”,a%b);
}
%是求余運算,得到a/b的整餘數。整型變數a和b可以進行求余運算,而實型變數則不允許進行「求余」運算。
3.將字元常量與字元串常量混淆。
char c;
c=”a”;
在這裡就混淆了字元常量與字元串常量,字元常量是由一對單引號括起來的單個字元,字元串常量是一對雙引號括起來的字元序列。C規定以「\」作字元串結束標誌,它是由系統自動加上的,所以字元串「a」實際上包含兩個字元:『a’和『\’,而把它賦給一個字元變數是不行的。
4.忽略了「=」與「==」的區別。
在許多高級語言中,用「=」符號作為關係運算符「等於」。如在BASIC程序中可以寫
if (a=3) then …
但C語言中,「=」是賦值運算符,「==」是關係運算符。如:
if (a==3) a=b;
前者是進行比較,a是否和3相等,後者表示如果a和3相等,把b值賦給a。由於習慣問題,初學者往往會犯這樣的錯誤。
5.忘記加分號。
分號是C語句中不可缺少的一部分,語句末尾必須有分號。
a=1
b=2
編譯時,編譯程序在「a=1」後面沒發現分號,就把下一行「b=2」也作為上一行語句的一部分,這就會出現語法錯誤。改錯時,有時在被指出有錯的一行中未發現錯誤,就需要看一下上一行是否漏掉了分號。
{ z=x+y;
t=z/100;
printf(“%f”,t);
}
對於複合語句來說,最後一個語句中最後的分號不能忽略不寫(這是和PASCAL不同的)。
6.多加分號。
對於一個複合語句,如:
{ z=x+y;
t=z/100;
printf(“%f”,t);
};
複合語句的花括弧後不應再加分號,否則將會畫蛇添足。
又如:
if (a%3==0);
I++;
本是如果3整除a,則I加1。但由於if (a%3==0)後多加了分號,則if語句到此結束,程序將執行I++語句,不論3是否整除a,I都將自動加1。
再如:
for (I=0;I5;I++);
{scanf(“%d”,x);
printf(“%d”,x);}
本意是先後輸入5個數,每輸入一個數後再將它輸出。由於for()後多加了一個分號,使循環體變為空語句,此時只能輸入一個數並輸出它。
7.輸入變數時忘記加地址運算符「」。
int a,b;
scanf(“%d%d”,a,b);
這是不合法的。Scanf函數的作用是:按照a、b在內存的地址將a、b的值存進去。「a」指a在內存中的地址。
8.輸入數據的方式與要求不符。①scanf(“%d%d”,a,b);
輸入時,不能用逗號作兩個數據間的分隔符,如下面輸入不合法:
3,4
輸入數據時,在兩個數據之間以一個或多個空格間隔,也可用回車鍵,跳格鍵tab。
②scanf(“%d,%d”,a,b);
C規定:如果在「格式控制」字元串中除了格式說明以外還有其它字元,則在輸入數據時應輸入與這些字元相同的字元。下面輸入是合法的:
3,4
此時不用逗號而用空格或其它字元是不對的。
3 4 3:4
又如:
scanf(“a=%d,b=%d”,a,b);
輸入應如以下形式:
a=3,b=4
9.輸入字元的格式與要求不一致。
在用「%c」格式輸入字元時,「空格字元」和「轉義字元」都作為有效字元輸入。
scanf(“%c%c%c”,c1,c2,c3);
如輸入a b c
字元「a」送給c1,字元「 」送給c2,字元「b」送給c3,因為%c只要求讀入一個字元,後面不需要用空格作為兩個字元的間隔。
10.輸入輸出的數據類型與所用格式說明符不一致。
例如,a已定義為整型,b定義為實型
a=3;b=4.5;
printf(“%f%d\n”,a,b);
編譯時不給出出錯信息,但運行結果將與原意不符。這種錯誤尤其需要注意。
11.輸入數據時,企圖規定精度。
scanf(“%7.2f”,a);
這樣做是不合法的,輸入數據時不能規定精度。
12.switch語句中漏寫break語句。
例如:根據考試成績的等級列印出百分制數段。
switch(grade)
{ case ‘A’:printf(“85~100\n”);
case ‘B’:printf(“70~84\n”);
case ‘C’:printf(“60~69\n”);
case ‘D’:printf(“60\n”);
default:printf(“error\n”);
由於漏寫了break語句,case只起標號的作用,而不起判斷作用。因此,當grade值為A時,printf函數在執行完第一個語句後接著執行第二、三、四、五個printf函數語句。正確寫法應在每個分支後再加上「break;」。例如
case ‘A’:printf(“85~100\n”);break;
13.忽視了while和do-while語句在細節上的區別。
(1)main()
{int a=0,I;
scanf(“%d”,I);
while(I=10)
{a=a+I;
I++;
}
printf(“%d”,a);
}
(2)main()
{int a=0,I;
scanf(“%d”,I);
do
{a=a+I;
I++;
}while(I=10);
printf(“%d”,a);
}
可以看到,當輸入I的值小於或等於10時,二者得到的結果相同。而當I10時,二者結果就不同了。因為while循環是先判斷後執行,而do-while循環是先執行後判斷。對於大於10的數while循環一次也不執行循環體,而do-while語句則要執行一次循環體。
14.定義數組時誤用變數。
int n;
scanf(“%d”,n);
int a[n];
數組名後用方括弧括起來的是常量表達式,可以包括常量和符號常量。即C不允許對數組的大小作動態定義。
15.在定義數組時,將定義的「元素個數」誤認為是可使的最大下標值。
main()
;
printf(“%d”,a[10]);
}
C語言規定:定義時用a[10],表示a數組有10個元素。其下標值由0開始,所以數組元素a[10]是不存在的。
16.初始化數組時,未使用靜態存儲。
int a[3]=;
這樣初始化數組是不對的。C語言規定只有靜態存儲(static)數組和外部存儲(exterm)數組才能初始化。應改為:
static int a[3]=;
17.在不應加地址運算符的位置加了地址運算符。
scanf(“%s”,str);
C語言編譯系統對數組名的處理是:數組名代表該數組的起始地址,且scanf函數中的輸入項是字元數組名,不必要再加地址符。應改為:
scanf(“%s”,str);
18.同時定義了形參和函數中的局部變數。
int max(x,y)
int x,y,z;
{z=xy?x:y;
return(z);
}
形參應該在函數體外定義,而局部變數應該在函數體內定義。應改為:
int max(x,y)
int x,y;
{int z;
z=xy?x:y;
return(z);
}
C語言心得體會
通過這次實訓,增加了我學習軟體技術的興趣,雖然還不明確軟體技術包含的具體內容,但從C語言這門課程開始,已發現程序設計的樂趣,在學習C語言的過程中也學到了許多計算機應用基礎知識,對計算機的機體也有了一個大體的了解。
這次實訓是老師給了范常式序,經過自己的改寫,實現要求。先做簡單的輸出,一步步的再做其它圖案,在實際操作過程中犯的一些錯誤還會有意外的收穫,感覺實訓很有意思。在具體操作中對這學期所學的C語言的理論知識得到鞏固,達到實訓的基本目的,也發現自己的不足之出,在以後的上機中應更加註意,同時體會到C語言具有的語句簡潔,使用靈活,執行效率高等特點。發現上機實訓的重要作用,特別是對數組和循環有了深刻的理解。
通過實際操作,學會 C語言程序編程的基本步驟、基本方法,開發了自己的邏輯思維能力,培養了分析問題、解決問題的能力。深刻體會到「沒有做不到的,只有想不到的」,「團結就是力量」,「實踐是檢驗真理的標準」,「不恥下問」……的寓意。
計時在此希望以後應多進行這樣的實訓,加長設間,培養學生獨立思考問題的能力,提高實際操作水平。
八、參考資料 :《C語言程序設計教程》
《C語言程序設計》項目設計
這種東西很多了,隨便搜索一大堆:這是個學生成績的!
#include iostream.h
#include iomanip.h
#include fstream
#include vector
#include malloc.h
#include stdlib.h
#include string
#include process.h
#include stdio.h
//#define NULL 0
int const Q=20;
#define LEN sizeof(struct student)
using namespace std;
int n=0; //定義一個全局變數統計學生人數
//—————定義一個學生考試信息的結構體
struct student
{
char name[Q]; //用來存放姓名的
char sex[Q]; //用來存放性別的
long int id; //用來存放准考證號的
int score[4]; //用來存放分數的
int total; //用來存放總分數的
struct student *next;
};
//student向量容器
vector student stu;
//————–學生類
class Information
{
public:
Information() ; //構造函數.
~Information() ; //析構函數.
student *creat();//建立鏈表函數。
void output(student *head);
int count(student *head);//定義函數count()統計考生總數
student *insert(student*head);//指針函數*insert()用來添加考生信息.
student *cancel(student *head,long int num);//指針函數*cancel()用來刪除考生信息.
student *find(student *head,long int num); //指針函數*find()用來查找考生信息.
void inorder(student *head);//定義inorder()函數將考生的總分從大到小排列並輸出
void average( student *head);//求學生成績的平均分的函數
void save(student *head);//保存函數
student *Read();//讀取函數
private:
student *p1,*p2,*p3,*head,st;
};
Information::Information()
{
cout” ******************************************************************************\n”;
cout” ————————歡迎您使用學生成績管理系統————————\n”;
cout” ******************************************************************************\n\n”;
}
Information::~Information()
{
cout” ******************************************************************************\n”;
cout” ————————謝謝您使用學生成績管理系統————————\n”;
cout” ******************************************************************************\n”;
}
student *Information::creat(void)
{//定義一個指向struct student的結構體指針函數*creat()用來增加考生信息.
char ch[Q];n=0; //用來存放姓名的
p1=p2=(student *)malloc(LEN);//調用malloc()函數用來開闢一個新的存儲單元
cout” ————-請建立學生考試信息表,在姓名處鍵以 ! 結束輸入。————–“endl;
cout” 姓名:”;
cinch;
head=NULL; //給指針head賦初值
while (strcmp(ch,”!”)!=0)
{//調用字元比較函數strcmp()用來判斷是否繼續輸入
char str[10];
int flag=0;
p1=(student *)malloc(LEN);//調用malloc()函數用來開闢一個新的存儲單元
strcpy(p1-name,ch); //將循環結構前面輸入的姓名複製到結構體名為p1的數組name中
cout” 性別:”;
cinp1-sex;
cout” 准考證號(8位):”;
do{
cinstr;
if(atol(str)99999999 || atol(str)1)
cout”對不起,請正確輸入!!!\n”;
else
{
p1-id=atol(str); flag=1;
}
}while(flag==0);
flag=0;
cout” 計算機組成原理成績:”;
do{
cinstr;
if(atoi(str)100 || atoi(str)1)
cout”對不起,請輸入1-100之間的數字!!\n”;
else
{
p1-score[0]=atoi(str); flag=1;
}
}while(flag==0);
flag=0;
cout” 概率統計成績:”;
do{
cinstr;
if(atoi(str)100 || atoi(str)1)
cout”對不起,請輸入1-100之間的數字!!\n”;
else
{ p1-score[1]=atoi(str); flag=1;}
}while(flag==0);
flag=0;
cout” 英語成績:”;
do{
cinstr;
if(atoi(str)100 || atoi(str)1)
cout”對不起,請輸入1-100之間的數字!!\n”;
else
{ p1-score[2]=atoi(str); flag=1;}
}while(flag==0);
flag=0;
cout” C++成績:”;
do{
cinstr;
if(atoi(str)100 || atoi(str)1)
cout”對不起,請輸入1-100之間的數字!!\n”;
else
{ p1-score[3]=atoi(str); flag=1;}
}while(flag==0);
flag=0;
p1-total=p1-score[0]+p1-score[1]+p1-score[2]+p1-score[3];//計算總分
if(n==0)head=p1;//如果是輸入第一組學生考試信息就將指針p1賦給指針head
else p2-next=p1;//否則將p1賦給p2所指結構體的next指針
p2=p1;//將指針p1賦給指針p2
n++; //將n的值加1
cout” 姓名:”;
cinch;//將輸入的姓名存放到字元數組ch中
}
p2-next=NULL;//將p2所指結構體的next指針重新賦空值
return (head);//將輸入的第一組學生考試信息返回
}
//—————定義output()函數將考生的信息從頭指針所指內容開始輸出
void Information::output(student *head)
{
if(head==NULL) cout” 這是一個空表,請先輸入考生成績.\n”;
else{
cout”——————————————————————————-\n”;
cout” *學生考試成績信息表*\n”;
cout”——————————————————————————-\n”;
cout”准考證號 姓 名 性別 計算機組成原理 概率統計 英語 C++ 平均分 總分\n”;
cout”——————————————————————————-\n”;
p1=head;//將頭指針賦給p
do
{
coutsetw(8)p1-id
setw(9)p1-name
setw(8)p1-sex
setw(13)p1-score[0]
setw(16)p1-score[1]
setw(10)p1-score[2]
setw(9)p1-score[3]
setw(6)p1-total/4.0
setw(11)p1-totalendl;
cout”——————————————————————————-\n”;
p1=p1-next;//將下一組考生信息的next指針賦給p
}while(p1!=NULL);//若指針p非空則繼續,目的是把所有的考生信息都傳給指針p然後輸出.
}
}
//————統計學生人數的函數
int Information::count(struct student *head)//定義函數count()統計考生總數
{
if(head==NULL)
return(0);//若指針head為空返回值為0
else return(1+count(head-next));//函數的遞歸調用
}
//———–插入學生的成績的函數
student *Information::insert( student *head)
//插入新結點定義一個指向struct student的結構體指針函數*insert()用來添加考生信息.
{
char str[10];
int flag=0;
cout”\t—————-請輸入新增學生成績信息—————-\n”endl;
p1=(student *)malloc(LEN); //使p1指向插入的新結點
cout” 姓名:”;
cinp1-name; //將輸入的姓名存放到結構體名為p1的數組name中
cout” 性別:”;
cinp1-sex;
cout” 准考證號(8位):”;
do{
cinstr;
if(atol(str)99999999 || atol(str)1)
cout”對不起,請請正確輸入!!!\n”;
else
{p1-id=atol(str); flag=1; }
}while(flag==0);
flag=0;
cout” 計算機組成原理成績:”;
do{
cinstr;
if(atoi(str)100 || atoi(str)1)
cout”對不起,請輸入1-100之間的數字!!\n”;
else
{ p1-score[0]=atoi(str); flag=1;}
}while(flag==0);
flag=0;
cout” 概率統計成績:”;
do{
cinstr;
if(atoi(str)100 || atoi(str)1)
cout”對不起,請輸入1-100之間的數字!!\n”;
else
{ p1-score[1]=atoi(str); flag=1;}
}while(flag==0);
flag=0;
cout” 英語成績:”;
do{
cinstr;
if(atoi(str)100 || atoi(str)1)
cout”對不起,請輸入1-100之間的數字!!\n”;
else
{ p1-score[2]=atoi(str); flag=1;}
}while(flag==0);
flag=0;
cout” C++成績:”;
do{
cinstr;
if(atoi(str)100 || atoi(str)1)
cout”對不起,請輸入1-100之間的數字!!\n”;
else
{ p1-score[3]=atoi(str); flag=1;}
}while(flag==0);
flag=0;
p1-total=p1-score[0]+p1-score[1]+p1-score[2]+p1-score[3];//計算總分
p2=head;//將頭指針賦給p2
if(head==NULL) //若沒調用次函數以前的頭指針head為空
{
head=p1;p1-next=NULL;
}//則將p1賦給頭指針head並將p1所指結構體成員指針next賦空值
else
{
while((p1-idp2-id)(p2-next!=NULL))
{
p3=p2;//p3指向原p2指向的結點
p2=p2-next;
}//p2後移一個結點
if(p1-id=p2-id)
{
if(head==p2)
{
p1-next=head;
head=p1;
} //插入到第一個結點之前
else
{
p3-next=p1;
p1-next=p2;
} //插入到p3所指結點之後
}
else
{
p2-next=p1;
p1-next=NULL;
} //插入到尾結點之後
}
n++;//將學生人數加1
cout”\t你輸入的學生信息已經成功插入”endl;
return (head);
}
//————刪除函數
student *Information::cancel(student *head,long int num)//定義一個指向struct student的結構體指針函數*delete()用來刪除考生信息.
{
if(head==NULL)//若調用次函數以前的頭指針head為空
{
return(head);
}
else
{
p1=head;//否則將頭指針賦給p1
while(num!=p1-idp1-next!=NULL)//尋找要刪除的結點當p1所指的學生准考證號不是輸入的學生准考證號並且p1所指的next指針不為空
{
p2=p1;
p1=p1-next;
}//p2指向原p1指向的結點p1後移一個結點
if(num==p1-id)//如果輸入的學生准考證號是p1所指的學生准考證號//結點找到後刪除
{
if(p1==head) head=p1-next;//如果head指針和p1指針相等則將下一個結點賦給指針head
else
p2-next=p1-next;//否則將p1所指結點賦給p2所指結點將要刪除的學生信息跳過去
cout” 刪除准考證號為”num”的學生\n”;
n–;//將學生人數減1
}
return(head);//將頭指針返回
}
}
//————查找函數
student *Information::find(student *head,long int num)
//定義一個指向struct student的結構體指針函數*find()用來查找考生信息.
{
if(head==NULL)//若調用次函數以前的頭指針head為空
{
cout” 這是一個空表,請先輸入考生成績.\n”;
return(head);
}
else
{
p1=head;//否則將頭指針賦給p1
while(num!=p1-idp1-next!=NULL)
//尋找結點當p1所指的學生准考證號不是輸入的學生准考證號並且p1所指的next指針不為空
{
p1=p1-next;
}//p2指向原p1指向的結點p1後移一個結點
if(num==p1-id)//如果要查找的學生准考證號是p1所指的學生准考證號
{
cout”——————————————————————————\n”;
cout”准考證號 姓名 性別 計算機組成原理 概率統計 英語 C++ 平均分 總分 \n”;
cout”——————————————————————————\n”;
coutsetw(8)p1-id
setw(9)p1-name
setw(8)p1-sex
setw(13)p1-score[0]
setw(16)p1-score[1]
setw(10)p1-score[2]
setw(9)p1-score[3]
setw(6)p1-total/4.0
setw(11)p1-totalendl;
cout”——————————————————————————\n”;
}
else
cout” 沒找到准考證號為”num”的學生.\n”; //結點沒找到
return(head);
}
}
//————定義inorder()函數將考生的總分從大到小排列並輸出
void Information::inorder(student *head)
{
int i,k,m=0,j;
student *p[Q];//定義一個指向struct student的結構體指針數組p
if(head!=NULL)//如果頭指針是空則繼續
{ m=count(head);
cout”——————————————————————————\n”;
cout”學生考試成績統計表\n”;
cout”——————————————————————————\n”;
cout”准考證號 姓 名 性別 計算機組成原理 概率統計 英語 C++ 平均分 總分 名次\n”;
cout”——————————————————————————\n”;
p1=head;
for(k=0;km;k++)
{
p[k]=p1;
p1=p1-next;
}
for(k=0;km-1;k++) //選擇排序法
for(j=k+1;jm;j++)
if(p[k]-totalp[j]-total)
{
p2=p[k];
p[k]=p[j];
p[j]=p2;
} //從大到小排列的指針
for(i=0;im;i++)
{
coutsetw(8)p1-id
setw(9)p1-name
setw(8)p1-sex
setw(13)p1-score[0]
setw(16)p1-score[1]
setw(10)p1-score[2]
setw(9)p1-score[3]
setw(6)p1-total/4.0
setw(11)p1-totalendl;
cout”——————————————————————————\n”;
}
}
}
//————求各科平均分成績的函數
void Information::average(student *head)
{
int k,m;
float arg1=0,arg2=0,arg3=0,arg4=0;
if(head==NULL)//如果頭指針是空則繼續
{
cout” 這是一個空表,請先輸入考生成績.\n”;
}
else
{
m=count(head);
p1=head;
for(k=0;km;k++)
{
arg1+=p1-score[0];
arg2+=p1-score[1];
arg3+=p1-score[2];
arg4+=p1-score[3];
p1=p1-next;
}
arg1/=m;arg2/=m;arg3/=m;arg4/=m;
cout”全班單科成績平均分\n”;
cout”——————————————————————————\n”;
cout” 計算機組成原理平均分:”setw(7)arg1
” 概率統計平均分:”setw(7)arg2
” 英語平均分:”setw(7)arg3
” C++平均分:”setw(7)arg4endl;
cout”——————————————————————————\n”;
}
}
//——————-保存函數.
void Information::save(student *head)
{
ofstream out(“data.txt”,ios::out);
outcount(head)endl;
while(head!=NULL)
{ outhead-name”\t”
head-id”\t””\t”
head-sex”\t”
head-score[0]”\t”
head-score[1]”\t”
head-score[2]”\t”
head-score[3]”\t”
head-totalendl;
head=head-next;
}
}
//———————————讀取函數的實現
student *Information::Read()
{ int i=0;
p1=p2=( student *)malloc(LEN);
head=NULL;
ifstream in(“data.txt”,ios::out);
ini;
if(i==0){cout” data.txt 文件中的數據為空,請先輸入數據。”endl; return 0;}
else {
cout” …………………………………………………………………………………………”endl;
for(;i0;i–)
{ p1=(student *)malloc(LEN);
cinst.namest.idst.sex
st.score[0]st.score[1]st.score[2]st.score[3]
st.total;
strcpy(p1-name,st.name);
p1-id=st.id;
strcpy(p1-sex,st.sex);
p1-score[0]=st.score[0];
p1-score[1]=st.score[1];
p1-score[2]=st.score[2];
p1-score[3]=st.score[3];
p1-total=st.total;
if(n==0)head=p1;//如果是輸入第一組學生考試信息就將指針p1賦給指針head
else p2-next=p1;//否則將p1賦給p2所指結構體的next指針
p2=p1;//將指針p1賦給指針p2
n++; //將n的值加1
//顯示讀入數據
cout” “p1-name”\t”
p1-id”\t””\t”
p1-sex”\t”
p1-score[0]”\t”
p1-score[1]”\t”
p1-score[2]”\t”
p1-score[3]”\t”
p1-totalendl;
cout” …………………………………………………………………………………………”endl;
//
}
cout” 數據已經成功讀取完畢。”endl;
p2-next=NULL;
return (head);
}
}
//——————————主函數.
int main(void)
{
Information person;
student *head=NULL;
char str[10];
int flag=0;
int choice;
long int i;
head=person.Read();
do{
cout”┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓”;
cout”┃ 學生成績管理系統主菜單界面 ┃”;
cout”┃ 讀取數據請輸入數字零 ┃”;
cout”┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫”;
cout”┃ ①.輸入學生成績 ┃”;
cout”┃ ②.顯示學生成績 ┃”;
cout”┃ ③.排序統計成績 ┃”;
cout”┃ ④.查找學生成績 ┃”;
cout”┃ ⑤.增加學生成績 ┃”;
cout”┃ ⑥.刪除學生成績 ┃”;
cout”┃ ⑦.保存退出系統 ┃”;
cout”┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛”;
cout”請輸入您的選擇(1–7):( )\b\b”;
cinstr;
if(atoi(str)7 || atoi(str)1)
cout”對不起,請輸入1-7這幾個數字!!\n”;
else
{
choice=atoi(str);
switch(choice)
{
case 1:
head=person.creat();
break;
case 2:
person.output(head);
break;
case 3:
person.inorder(head);
person.average(head);
cout” 參加考試的學生人數為:”person.count(head)”人\n”;
break;
case 4:
cout” 請輸入要查找的准考證號(8位):”;
do{
cinstr;
if(atol(str)99999999 || atol(str)1)
cout”對不起,請輸入正確輸入!!!\n”;
else
{i=atol(str); flag=1; }
}while(flag==0);
flag=0;
person.find(head,i);
break;
case 5:
head=person.insert(head);
person.output(head);
break;
case 6:
cout” 請輸入要刪除的准考證號(8位):”;
do{
cinstr;
if(atol(str)99999999 || atol(str)1)
cout”對不起,請輸入正確輸入!!!h\n”;
else
{i=atol(str); flag=1; }
}while(flag==0);
flag=0;
head=person.cancel(head,i);
person.output(head);
break;
case 7:
person.save(head);
cout”文件已保存!可以安全退出!!!”endl;
break;
default :cout” 對不起,您的輸入有誤,請重新輸入。\n”;
break;
}
}
}while(choice!=7);
return 0;
}
C語言程序設計中應注意哪些問題
1.先學習C語言的基礎知識。現在正在學C語言的在校學生可以直接進入第2步學習。
2.按照《C語言程序設計入門學習六步曲》進行上機練習。
3.在上機練習時要養成良好的編程風格。點擊查看C語言的編程風格
4.積极參加C、C++興趣小組,養成和老師與同學交流習慣,從而相互收益。有時別人不經意的一句話可能使你茅塞頓開–「一句話點醒夢中人」。
5.及時總結自己的學習經驗,養成寫C語言日記的習慣。軟體有編程日記功能。
6.從網上或教材上找一個自己感興趣的題目(選題時根據自己的能力,可先易後難,培養自己的成就感,如果有了成就感,即使再苦再累還是感覺C語言學習是一件快樂的事,同學們喜歡打遊戲,經常通宵達旦地玩遊戲也樂而不疲就是這個道理)進行實戰訓練,提高自己的C語言綜合應用能力。
7. 由於C語言靈活、強大,初學者要全面地掌握它是不可能的,因此在學習C語言的過程中,不要在細枝末節上浪費精力(比如++、–用於表達式的計算,實際上是沒有意義的),但一定要熟練掌握C語言的流程式控制制語句、數組、函數、指針等基礎知識的應用,為學習面向對象程序設計打下堅實的基礎。如果這些知識你學不好,要後續學習好C++、可視化的程序設計Visual C++或C++Builder就像空中樓閣,是不現實的。
C語言程序設計入門學習六步曲
筆者在從事教學的過程中,聽到同學抱怨最多的一句話是:老師,上課我也能聽懂,書上的例題也能看明白,可是到自己動手做編程時,卻不知道如何下手。發生這種現象的原因有三個:
一、所謂的看懂聽明白,只是很膚淺的語法知識,而我們編寫的程序或軟體是要根據要解決問題的實際需要控制程序的流程,如果你沒有深刻地理解C語言的語句的執行過程(或流程),你怎麼會編寫程序解決這些實際問題呢?
二、用C語言編程解決實際問題,所需要的不僅僅是C語言的編程知識,還需要相關的專業知識。例如,如果你不知道長方形的面積公式,即使C語言學得再好你也編不出求長方形的面積的程序來。
三、C語言程序設計是一門實踐性很強的課程,「紙上談兵」式的光學不練是學不好C語言的。例如,大家都看過精彩自行車雜技表演,假如,你從來沒有騎過自行車,光聽教練講解相關的知識、規則、技巧,不要說上台表演、就是上路你恐怕都不行。
出現問題原因清楚了,那麼如何學習呢?請你看【C語言學習六步曲】
在程序開發的過程中,上機調試程序是一個不可缺少的重要環節。「三分編程七分調試」,說明程序調試的工作量要比編程大得多。這裡以如何上機調試C程序來說明C語言的學習方法。
第一步、驗證性練習
在這一步要求按照教材上的程序實例進行原樣輸入,運行一下程序是否正確。在這一步基本掌握C語言編程軟體的使用方法(包括新建、打開、保存、關閉C程序,熟練地輸入、編輯C程序;初步記憶新學章節的知識點、養成良好的C語言編程風格)。
初學者最容易犯的錯誤是:
1、沒有區分開教材上的數字1和字母l,字母o和數字0的區別,造成變數未定義的錯誤。另一個易錯點是將英文狀態下的逗號,分號;括弧()雙引號””輸入出入成中文狀態下的逗號,分號;括弧(),雙引號「」造成非法字元錯誤。
2、C語言初學者易犯語法錯誤:使用未定義的變數、標示符(變數、常量、數組、函數等)不區分大小寫、漏掉「;」、「{」與「}」、「(」與「)」不匹、控制語句(選擇、分支、循環)的格式不正確、調用庫函數卻沒有包含相應的頭文件、調用未C聲明的自定義函數、調用函數時實參與形參不匹配、數組的邊界超界等。
3、修改C語言語法錯誤時要注意以下兩點:
(1)、由於C語言語法比較自由、靈活,因此錯誤信息定位不是特別精確。例如,當提示第10行發生錯誤時,如果在第10行沒有發現錯誤,從第10行開始往前查找錯誤並修改之。
(2)、一條語句錯誤可能會產生若干條錯誤信息只要修改了這條錯誤,其他錯誤會隨之消失。特別提示:一般情況下,第一條錯誤信息最能反映錯誤的位置和類型,所以調試程序時務必根據第一條錯誤信息進行修改,修改後,立即運行程序,如果還有很多錯誤,要一個一個地修改,即,每修改一處錯誤要運行一次程序。
第二步、照葫蘆畫瓢
在第一步輸入的C程序的基礎上進行試驗性的修改,運行一下程序看一看程序結果發生了什麼變化,分析結果變化的原因,加深新學知識點的理解。事實上這和第一步時同步進行的,實現「輸入」加深知識的記憶,「修改」加深對知識的理解。記憶和理解是相輔相成的,相互促進。
例如:將最簡單的Hello World!程序
#include “stdio.h”
int main()
{
printf(“Hello World!\n”);
return 0;
}
中的
printf(“Hello World!\n”);
中的Hello World!改成你的姓名,運行一下程序,看有什麼變化?
再如求1+2+3…+100的和的程序
#include stdio.h
main()
{
int i,sum=0;
for(i=1;i=100;i++)
{
sum=sum+i;
}
printf(“sum=%d\n”,sum);
}
第1次將for(i=1;i=100;i++)中的100改成50,運行一下程序,看有什麼變化?
第2次將for(i=1;i=100;i++)中的i++改成i=i+2,運行一下程序,看有什麼變化?
找出程序結果變化的原因,就加深了對C語句的理解。
第三步、不看教材看是否能將前兩步的程序進行正確地輸入並運行。
在這一步要求不看教材,即使程序不能運行,看能否將其改正,使其能正確運行。目的是對前兩步的記憶、理解進一步強化。
第四步、增強程序的調試能力
在教材中每章都有C語言初學者易犯的錯誤,按照易出錯的類型,將教材中的正確的程序改成錯誤的程序,運行一下程序,看出現的錯誤信息提示,並記下錯誤信息,再將程序改成正確的,運行一下程序。這樣反覆修改,就能夠學習C語言程序發生錯誤的原因和修改錯誤的能力。
注意:每次只改錯一個地方,目的是顯示發生該錯誤的真正原因,避免一次改動多個地方,搞清發生錯誤的真正原因,切記!!!!
注意:上機調試程序時要帶一個記錄本,記下英文錯誤提示信息和解決該錯誤問題的方法,積累程序調試經驗,避免在編程犯同樣的錯誤,切記!!!!。
例如,將Hello World程序中語句
printf(“Hello World!\n”);
中的;改成中文的分號;
運行一下程序,看有什麼結果?
調試程序是一種實踐性很強的事,光紙上談兵是是沒用的,就像游泳運動員只聽教練講解示範,而不親自下水練習,是永遠學不會游泳的。
即使在優秀的程序員編寫程序也會犯錯誤的,可能事最低級的語法錯誤,但他能快速發現錯誤並改正錯誤,而我們C語言初學者面對錯誤提示,不知道發生了什麼錯誤,如何改正,這就事差別。
第五步、研究典型的C語言程序,提高程序設計能力
C語言初學者遇到最多的困惑是:上課也能聽懂,書上的例題也能看明白,可是到自己動手做編程時,卻不知道如何下手。發生這種現象的原因是:所謂的看懂聽明白,只是很膚淺的語法知識,而沒有深刻地理解C語言的語句的執行過程(或流程)。
計算機是按照人的指令(編寫的程序)去執行的,如果不知道這些C語句在計算機中是如何執行的,你怎麼回靈活運用這些知識去解決實際問題呢?
解決問題的方法是要先理解C語言各種語句的流程(即計算機是如何執行這些語句的過程),然後研讀現成C語言經典程序,看懂別人事如何解決問題的,以提高自己的程序設計能力。
第六步、研究課程設計源成序,提高C語言的綜合應用能力.
C語言程序設計加註釋完成下列要求
C語言編程規範-注釋
規則:
1:一般情況下,源程序有效注釋量必須在20%以上。
說明:注釋的原則是有助於對程序的閱讀理解,在該加的地方都加了,注釋不宜太多也不能太少,注釋語言必須準確、易懂、簡潔。
2:說明性文件(如頭文件.h文件、.inc文件、.def文件、編譯說明文件.cfg等)頭部應進行注釋,注釋必須列出:版權說明、版本號、生成日期、作者、內容、功能、與其它文件的關係、修改日誌等,頭文件的注釋中還應有函數功能簡要說明。
示例:下面這段頭文件的頭注釋比較標準,當然,並不局限於此格式,但上述信息建議要包含在內。
/*************************************************
Copyright (C), 1988-1999, Tech. Co., Ltd.
File name: // 文件名
Author:
Version:
Date: // 作者、版本及完成日期
Description: // 用於詳細說明此程序文件完成的主要功能,與其他模塊
// 或函數的介面,輸出值、取值範圍、含義及參數間的控
// 制、順序、獨立或依賴等關係
Others: // 其它內容的說明
Function List: // 主要函數列表,每條記錄應包括函數名及功能簡要說明
1. ….
History: // 修改歷史記錄列表,每條修改記錄應包括修改日期、修改
// 者及修改內容簡述
1. Date:
Author:
Modification:
2. …
*************************************************/
3:源文件頭部應進行注釋,列出:版權說明、版本號、生成日期、作者、模塊目的/功能、主要函數及其功能、修改日誌等。
示例:下面這段源文件的頭注釋比較標準,當然,並不局限於此格式,但上述信息建議要包含在內。
/************************************************************
Copyright (C), 1988-1999, Tech. Co., Ltd.
FileName: test.cpp
Author:
Version :
Date:
Description: // 模塊描述
Version: // 版本信息
Function List: // 主要函數及其功能
1. ——-
History: // 歷史修改記錄
David 96/10/12 1.0 build this moudle
***********************************************************/
說明:Description一項描述本文件的內容、功能、內部各部分之間的關係及本文件與其它文件關係等。History是修改歷史記錄列表,每條修改記錄應包括修改日期、修改者及修改內容簡述。
4:函數頭部應進行注釋,列出:函數的目的/功能、輸入參數、輸出參數、返回值、調用關係(函數、表)等。
示例:下面這段函數的注釋比較標準,當然,並不局限於此格式,但上述信息建議要包含在內。
/*************************************************
Function: // 函數名稱
Description: // 函數功能、性能等的描述
Calls: // 被本函數調用的函數清單
Called By: // 調用本函數的函數清單
Table Accessed: // 被訪問的表(此項僅對於牽扯到資料庫操作的程序)
Table Updated: // 被修改的表(此項僅對於牽扯到資料庫操作的程序)
Input: // 輸入參數說明,包括每個參數的作
// 用、取值說明及參數間關係。
Output: // 對輸出參數的說明。
Return: // 函數返回值的說明
Others: // 其它說明
*************************************************/
5:邊寫代碼邊注釋,修改代碼同時修改相應的注釋,以保證注釋與代碼的一致性。不再有用的注釋要刪除。
6:注釋的內容要清楚、明了,含義準確,防止注釋二義性。
說明:錯誤的注釋不但無益反而有害。
7:避免在注釋中使用縮寫,特別是非常用縮寫。
說明:在使用縮寫時或之前,應對縮寫進行必要的說明。
8:注釋應與其描述的代碼相近,對代碼的注釋應放在其上方或右方(對單條語句的注釋)相鄰位置,不可放在下面,如放於上方則需與其上面的代碼用空行隔開。
示例:如下例子不符合規範。
例1:
/* get replicate sub system index and net indicator */
repssn_ind = ssn_data[index].repssn_index;
repssn_ni = ssn_data[index].ni;
例2:
repssn_ind = ssn_data[index].repssn_index;
repssn_ni = ssn_data[index].ni;
/* get replicate sub system index and net indicator */
應如下書寫
/* get replicate sub system index and net indicator */
repssn_ind = ssn_data[index].repssn_index;
repssn_ni = ssn_data[index].ni;
9:對於所有有物理含義的變數、常量,如果其命名不是充分自注釋的,在聲明時都必須加以注釋,說明其物理含義。變數、常量、宏的注釋應放在其上方相鄰位置或右方。
示例:
/* active statistic task number */
#define MAX_ACT_TASK_NUMBER 1000
#define MAX_ACT_TASK_NUMBER 1000 /* active statistic task number */
10:數據結構聲明(包括數組、結構、類、枚舉等),如果其命名不是充分自注釋的,必須加以注釋。對數據結構的注釋應放在其上方相鄰位置,不可放在下面;對結構中的每個域的注釋放在此域的右方。
示例:可按如下形式說明枚舉/數據/聯合結構。
/* sccp interface with sccp user primitive message name */
enum SCCP_USER_PRIMITIVE
{
N_UNITDATA_IND, /* sccp notify sccp user unit data come */
N_NOTICE_IND, /* sccp notify user the No.7 network can not */
/* transmission this message */
N_UNITDATA_REQ, /* sccp user’s unit data transmission request*/
};
11:全局變數要有較詳細的注釋,包括對其功能、取值範圍、哪些函數或過程存取它以及存取時注意事項等的說明。
示例:
/* The ErrorCode when SCCP translate */
/* Global Title failure, as follows */ // 變數作用、含義
/* 0 - SUCCESS 1 - GT Table error */
/* 2 - GT error Others - no use */ // 變數取值範圍
/* only function SCCPTranslate() in */
/* this modual can modify it, and other */
/* module can visit it through call */
/* the function GetGTTransErrorCode() */ // 使用方法
BYTE g_GTTranErrorCode;
12:注釋與所描述內容進行同樣的縮排。
說明:可使程序排版整齊,並方便注釋的閱讀與理解。
示例:如下例子,排版不整齊,閱讀稍感不方便。
void example_fun( void )
{
/* code one comments */
CodeBlock One
/* code two comments */
CodeBlock Two
}
應改為如下布局。
void example_fun( void )
{
/* code one comments */
CodeBlock One
/* code two comments */
CodeBlock Two
}
13:將注釋與其上面的代碼用空行隔開。
示例:如下例子,顯得代碼過於緊湊。
/* code one comments */
program code one
/* code two comments */
program code two
應如下書寫
/* code one comments */
program code one
/* code two comments */
program code two
14:對變數的定義和分支語句(條件分支、循環語句等)必須編寫注釋。
說明:這些語句往往是程序實現某一特定功能的關鍵,對於維護人員來說,良好的注釋幫助更好的理解程序,有時甚至優於看設計文檔。
15:對於switch語句下的case語句,如果因為特殊情況需要處理完一個case後進入下一個case處理,必須在該case語句處理完、下一個case語句前加上明確的注釋。
說明:這樣比較清楚程序編寫者的意圖,有效防止無故遺漏break語句。
示例(注意斜體加粗部分):
case CMD_UP:
ProcessUp();
break;
case CMD_DOWN:
ProcessDown();
break;
case CMD_FWD:
ProcessFwd();
if (…)
{
…
break;
}
else
{
ProcessCFW_B(); // now jump into case CMD_A
}
case CMD_A:
ProcessA();
break;
case CMD_B:
ProcessB();
break;
case CMD_C:
ProcessC();
break;
case CMD_D:
ProcessD();
break;
…
建議:
1:避免在一行代碼或表達式的中間插入注釋。
說明:除非必要,不應在代碼或表達中間插入注釋,否則容易使代碼可理解性變差。
2:通過對函數或過程、變數、結構等正確的命名以及合理地組織代碼的結構,使代碼成為自注釋的。
說明:清晰準確的函數、變數等的命名,可增加代碼可讀性,並減少不必要的注釋。
3:在代碼的功能、意圖層次上進行注釋,提供有用、額外的信息。
說明:注釋的目的是解釋代碼的目的、功能和採用的方法,提供代碼以外的信息,幫助讀者理解代碼,防止沒必要的重複注釋信息。
示例:如下注釋意義不大。
/* if receive_flag is TRUE */
if (receive_flag)
而如下的注釋則給出了額外有用的信息。
/* if mtp receive a message from links */
if (receive_flag)
4:在程序塊的結束行右方加註釋標記,以表明某程序塊的結束。
說明:當代碼段較長,特別是多重嵌套時,這樣做可以使代碼更清晰,更便於閱讀。
示例:參見如下例子。
if (…)
{
// program code
while (index MAX_INDEX)
{
// program code
} /* end of while (index MAX_INDEX) */ // 指明該條while語句結束
} /* end of if (…)*/ // 指明是哪條if語句結束
5:注釋格式盡量統一,建議使用”/* …… */”。
6:注釋應考慮程序易讀及外觀排版的因素,使用的語言若是中、英兼有的,建議多使用中文,除非能用非常流利準確的英文表達。
說明:注釋語言不統一,影響程序易讀性和外觀排版,出於對維護人員的考慮,建議使用中文。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/247154.html