?
1、找錯(cuò)
?
void test1() { char string[10]; char* str1="0123456789"; strcpy(string, str1); }
?
這里string數(shù)組越界,因?yàn)樽址L(zhǎng)度為10,還有一個(gè)結(jié)束符’’。所以總共有11個(gè)字符長(zhǎng)度。string數(shù)組大小為10,這里越界了。
PS:使用strcpy函數(shù)的時(shí)候一定要注意前面目的數(shù)組的大小一定要大于后面字符串的大小,否則便是訪問越界。
?
?
void test2() { char string[10], str1[10]; for(i=0; i<10;i ) { str1[i] ='a'; } strcpy(string, str1); }
?
這里有一個(gè)一眼就能看出的問題,那就是變量i沒有定義,這在代碼編譯階段編譯器可以幫你發(fā)現(xiàn),很容易搞定。然而很多問題是自己造成的漏洞,編譯器是幫不上什么忙的。這里最大的問題還是str1沒有結(jié)束符,因?yàn)閟trcpy的第二個(gè)參數(shù)應(yīng)該是一個(gè)字符串常量。該函數(shù)就是利用判斷第二個(gè)參數(shù)的結(jié)束符來得到是否拷貝完畢。所以在for循環(huán)后面應(yīng)加上str1p[9] = ‘’;
PS:字符數(shù)組和字符串的最明顯的區(qū)別就是字符串會(huì)被默認(rèn)的加上結(jié)束符’’。
?
?
void test3(char* str1) { char string[10]; if(strlen(str1)<=10) { strcpy(string, str1); } }
?
這里的問題仍是越界問題。strlen函數(shù)得到字符串除結(jié)束符外的長(zhǎng)度。如果這里是<=10話,就很明顯越界了。
小結(jié):上面的三個(gè)找錯(cuò)的函數(shù),主要是考查對(duì)字符串和字符數(shù)組的概念的掌握以及對(duì)strcpy函數(shù)和strlen函數(shù)的理解。
2、找錯(cuò)
?
?
DSN get_SRM_no() { static int SRM_no; int I; for(I=0;I { SRM_no %= MAX_SRM; if(MY_SRM.state==IDLE) { break; } } if(I>=MAX_SRM) return (NULL_SRM); else return SRM_no; }
?
這里for循環(huán)的判斷語句是后來我加上的,估計(jì)在網(wǎng)上流傳的時(shí)候被人給弄丟了,根據(jù)對(duì)程序的分析,給補(bǔ)上了。估計(jì)錯(cuò)誤應(yīng)該不是這兒。
簡(jiǎn)單的閱讀一下這個(gè)函數(shù),可以大概的可以猜測(cè)出這個(gè)函數(shù)的功能是分配一個(gè)空閑的SRAM塊。方法:從上次分配的RAM塊后的RAM塊開始檢測(cè)SRAM每個(gè)RAM塊,看是否是IDLE狀態(tài),如果是IDLE則返回當(dāng)前的RAM塊的號(hào)SRM_no。如果所有的RAM塊都不是IDLE狀態(tài),則意味著無法分配一個(gè)RAM給函數(shù)調(diào)用者,返回一個(gè)表示沒有RAM可分配的標(biāo)志(NULL_SRM)。
經(jīng)過上面的分析,則這里可以知道,這個(gè)函數(shù)的錯(cuò)誤是for循環(huán)里面沒有給SRM_no這個(gè)變量累加1。
3、寫出程序運(yùn)行結(jié)果
?
?
int sum(int a) { auto int c=0; static int b=3; c =1; b =2; return(a b c); } void main() { int I; int a=2; for(I=0;I<5;I ) { printf("%d,", sum(a)); } }
?
運(yùn)行結(jié)果是:8,10,12,14,16,
在求和函數(shù)sum里面c是auto變量,根據(jù)auto變量特性知每次調(diào)用sum函數(shù)時(shí)變量c都會(huì)自動(dòng)賦值為0。b是static變量,根據(jù)static變量特性知每次調(diào)用sum函數(shù)時(shí)變量b都會(huì)使用上次調(diào)用sum函數(shù)時(shí)b保存的值。
簡(jiǎn)單的分析一下函數(shù),可以知道,若傳入的參數(shù)不變,則每次調(diào)用sum函數(shù)返回的結(jié)果,都比上次多2。所以答案是:8,10,12,14,16,
4、func(1) = ?
?
?
int func(int a) { int b; switch(a) { case 1: 30; case 2: 20; case 3: 16; default: 0; } return b; }
?
在 case 語句中可能忘記了對(duì)變量b賦值。如果改為下面的代碼:
?
?
int func(int a) { int b; switch(a) { case 1: b = 30; case 2: b = 20; case 3: b = 16; default: b = 0; } return b; }
?
因?yàn)閏ase語句中漏掉了break語句,所以無論傳給函數(shù)的參數(shù)是多少,運(yùn)行結(jié)果均為0。
關(guān)注公眾號(hào)C語言中文社區(qū),免費(fèi)領(lǐng)取200G C語言干貨資料
5、a[q - p] = ?
?
?
int a[3]; a[0]=0; a[1]=1; a[2]=2; int *p, *q; p=a; q=&a[2];
?
很明顯:a[q - p] = a[2] = 2;
6、內(nèi)存空間占用問題
定義 int **a[3][4], 則變量占有的內(nèi)存空間為:16位系統(tǒng)24,32位編譯系統(tǒng)中是48。
PS:公式:3 * 4 * sizeof(int **) 。
7、程序編寫
編寫一個(gè)函數(shù),要求輸入年月日時(shí)分秒,輸出該年月日時(shí)分秒的下一秒。如輸入2004年12月31日23時(shí)59分59秒,則輸出2005年1月1日0時(shí)0分0秒。
?
?
void ResetTheTime(int *year,int *month,int *date,int *hour,int *minute,int*second) { int dayOfMonth[12]={31,28,31,30,31,30,31,31,30,31,30,31}; if( *year < 0 || *month < 1 || *month > 12 || *date < 1 || *date > 31 || *hour < 0 || *hour > 23 || *minute < 0 ||*minute > 59|| *second<0 second="">60 ) return; if( *year@0 == 0 || *year0 != 0 && *year%4 == 0 ) dayOfMonth[1] = 29; if(*second >= 60) { *second = 0; *minute = 1; if(*minute >= 60) { *minute = 0; *hour = 1; if(*hour >= 24) { *hour = 0; *date = 1; if(*date > dayOfMonth[*month-1]) { *date = 1; *month = 1; if(*month > 12) { *month=1; *year = 1; } } } } } return; }
審核編輯:湯梓紅
評(píng)論