一、PTA實驗作業
題目1,簡單計算器:
1. 本題PTA提交列表
2. 設計思路
定義操作數num1,num2,結果result=0.運算符ch。
輸入num1
while (ch=getchar())!='='
輸入num2
switch(ch)
+ 運算 result=num1+num2 break
- 運算 result=num1-num2 break
* 運算 result=num1*num2 break
/ if num2==0,輸出錯誤 break
else 運算 result=num1/num2 break
default 輸出錯誤 break
num1=result 再下一次循環
輸出num1
3.代碼截圖
4.本題調試過程碰到問題及PTA提交列表情況說明。
1. 部分正確 :討論ch等於'/'及非法符號時答案錯誤
錯誤代碼:
case '/': //當運算符為'/'時分出數位0的特殊情況
if(num2==0){
printf("ERROR\n");//若分母為0,輸出錯誤 ,並跳出循環
break;
}
else{
result=num1/num2;break; //否則正常運算
default: printf("ERROR\n"); break; //除以上情況全部輸出錯誤
- 調試過程:
- 測試除數為0:
我發現:當switch判斷到是'/'號並且除數為0時,盡管已經輸出錯誤信息“ERROR,但break只能結束上面的while循環,循環外面的輸出num1的語句還是會執行,導致答案錯誤。
- 測試非法符號:
我發現:和上面那個是一樣的,當輸出錯誤信息“ERROR后,程序還在繼續執行,並沒有要停止導致答案錯誤。
- 解決辦法:意識到需要在輸出錯誤信息后結束程序,我去百度怎樣提前結束程序,將兩個break都改成return 0就解決了這兩個錯誤。而且我發現在switch語句中再加if語句時DEV它會自動在if語句內加上break.
2. 部分正確 :最小表達式錯誤,即只有一個操作數並無運算的情況。
錯誤代碼:
num1=result;//把每一次的結果放入num1中進行下一次的運算
}
printf("%d",result); //輸出結果
return 0;
-
調試過程:
即當沒有運算符時,程序不會進入進入while循環,導致輸出result時結果為result的初始值0. -
解決辦法:本來想在循環再加一句將num1的值賦給result的語句,后來想到既然num1里每次都存放着result來進入每一次的運算,那么結束時直接輸出num1也是一樣的效果。
3. 本題小結 :
return語句作用:
return 0放在main函數里頭的中間,程序就提前結束不執行往后的代碼了;
return語句在函數中的功能就是退出當前函數並提供一個返回值,函數被終止了,后面的語句就不會被執行了;
如果主函數的類型是 int main(){},那么就需要 return 0;
如果主函數的類型是 void main(){},那么就不需要返回值 ;
上面的情況同樣也適用於自定義的函數,但是自定義函數是返回一個具體變量或值。
-- 引用自百度知道
同時也搞清楚break的作用范圍:
break語句的調用,起到跳出循環或者分支語句作用。
也就是說,break只有兩種使用環境:
1 用於循環體內,包括for, while和do-while循環,作用為跳出break所在循環體。注意,如果是循環嵌套,而break出現在內層,那么只能跳出內層循環,無法跳出外層循環。
2 用於開關語句,即switch - case語句,起到跳出開關語句作用。用於switch嵌套時,與上述循環嵌套效果相同,只可以跳出所在開關語句。
-- 引用自百度知道
題目2:判斷合法標識符
1. 本題PTA提交列表
2. 設計思路
主函數:
定義數組a[80].i循環變量,repeat次數。
輸入repeat
for i=1 to i<=repeat
共repeat次
gets()讀入一行字符串。
調用all(a) if 返回值為1 輸出YES
else 輸出NO
int all(char a[ ])自定義判斷函數:
定義m循環變量
if (a[0] !(下划線,字母)) 返回0
else
for i=1 to a[i]!='\000'
if (a[i] !(下划線,字母,數字) 返回0
i++
直到a[i]='\000' 返回1
3.代碼截圖:
4.本題調試過程碰到問題及PTA提交列表情況說明。
1. 運行超時:剛開始沒用數組,感覺是因為這個導致沒在規定時間內運行結束,所以后面使用了數組。
2. 答案錯誤:其實這題兜兜轉轉用了好多種方法,最后我使用了數組與函數結合的方法解決,這里面最復雜的問題是討論遇到空格時的情況。
- 調試過程:
錯誤原因:當我輸入有空格的字符時,它進入函數直到讀到空格時返回0,輸出了No,但是它下一次讀入的是空格后的字符。
解決辦法:當得知是%s的問題以后,我去百度查資料怎樣解決%s遇空格結束的問題,所以我將字符串的讀取改為gets(),解決了這個問題。
用scanf只能錄入連續的字符串,遇到空格就結束,如果你要把空格也吞了,推薦用gets()就可把接收帶空格的字符串,它遇回車才結束的。
題目3:打印菱形圖案
1. 本題PTA提交列表
2. 設計思路
定義n,i放循環變量,space放空格,xing放*
for i=1 to n/2+1
上半部分
for space=1 to space<=n/2+1-i
輸出空格。space++,end
for xing=1 to xing<=2i-1
輸出*空格。xing++,end
換行i++,end
for i=1 to i<=n/2
下半部分
for space=1 to space<=i
輸出空格。space++,end
for xing=1 to xing<=n-2i
輸出*空格。xing++,end
換行i++,end
3.代碼截圖:
4.本題調試過程碰到問題及PTA提交列表情況說明。
1. 部分正確 :圖形不對稱,只關注到星號后面要有空格,忽略了前面的空格並不是以一個為單位輸出的
- 調試過程:
解決辦法:將每次輸出的空格改成兩個空格。
二、截圖本周題目集的PTA最后排名。
三、本周學習總結(3分)
1.你學會了什么?
1.1 一維數組如何定義、初始化?
- 定義:確定數組變量名,數組元素的類型,數組大小。
類型名 數組名 [數組長度];
- 初始化:
類型名 數組名[數組長度] = {初值表};
1.2 一維數組在內存中結構?可畫圖說明。數組名表示什么?
- 數組名是一個地址常量,存放數組內存空間的首地址。
1.3 為什么用數組?
- 數組是一組相同類型數據的有序集合,並且元素在其內存中連續存放。它的表達簡潔,可讀性好,便於使用循環結構。
1.4 介紹選擇法、冒泡法、直接插入排序如何排序?偽代碼展示.
- 選擇排序法:首先在未排序序列中找到最小元素,存放到排序序列的起始位置,然后,再從剩余未排序元素中繼續尋找最小元素,然后放到排序序列末尾(目前已被排序的序列)。以此類推,直到所有元素均排序完畢.
1.定義循環變量i,j和總個數n,以及中間量k,temp.數組a[n]
2.進入for(i = 0; i < n-1; i++)控制循環次數,n個數需要n-1次循環。
3.k賦值為i,在進入內循環for (j=i+1; j < n; j++) ,循環內判斷a[j] < a[k],若是則賦值k等於j.
4.重復第3步,直到j=n.
5.若k != i,temp賦值為a[k],a[k]賦值為a[i],a[i]賦值為temp,來交換a[k],a[i]的值。
6.重復第2步,直到i=n-1,結束循環。
- 冒泡排序法:它重復地走訪過要排序的數列,一次比較兩個元素,如果他們的順序錯誤就把他們交換過來。走訪數列的工作是重復地進行直到沒有再需要交換,也就是說該數列已經排序完成。
1.定義循環變量i,j,總個數n和數組a[n].中間量temp
2.進入for(i=0;i<10-1;i++)控制循環次數,n個數需要n-1次循環。
3.在進入內循環for(j=0;j<9-i;j++)每次比較n-i次,if判斷a[j]>a[j+1],若為真,temp賦值為a[j],a[j]賦值為a[j+1],a[j+1]賦值為temp,來交換a[j],a[j+1]的值。
4.重復第3步,直到j=9-i.結束內循環。
5.重復第2步,直到i=10-i.結束循環輸出數組內的數
- 直接插入排序:從序列中第二個數開始,插入前面已經排好的序列中,形成一個新的排序好的序列,以此類推到最后一個元素。
1.從第一個元素開始,temp=a[i],i為循環變量表示不斷往后取數,並賦值給temp
2.取出下一個元素,在已經排序的元素序列中從后向前判斷,並利用j==1標記它的初始位置
3.找到新元素小於已排序的元素,即temp<a[j-1],就將已排序的該元素移到下一位置 ,將新元素插進去,j--
4.重復步驟3,直到找到新元素大於或者等於已排序的元素的位置,即temp>=a[j-1]
5.將新元素插入到該位置中,將a[j-1]的值賦給a[j],將temp的值賦給a[j]
6.重復步驟2,直至將所有數據取完
1.5 介紹什么是二分查找法?它和順序查找法區別?
- 二分查找法:取中間元素與查找元素進行比較,如果查找元素比中間元素大,則在中間元素右邊查找,如果查找元素比中間元素小,則在中間元素的左邊查找。
- 順序查找法:從表的第一個元素開始一個一個向下查找,如果有和目標一致的元素,查找成功;如果到最后一個元素仍沒有目標元素,則查找失敗。
- 二分法的優點是比較次數少,查找速度快,平均性能好。缺點是要求查表為順序表,插入、刪除困難。
1.6 二維數組如何定義、初始化?
- 定義:
類型名 數組名 [行長度] [列長度];
- 初始化:
- 分行賦初值:
類型名 數組名 [行長度] [列長度] = { {初值表0},······,{初值表k},······};
- 順序賦初值
類型名 數組名 [行長度] [列長度] = {初值表};
1.7 矩陣轉置怎么實現?
int main()
{
int i, j, b[3][3];
int a[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
printf("矩陣原型:\n");
for(i = 0; i < 3; i++)
{
for(j = 0; j < 3; j++)
{
b[j][i] = a[i][j];
printf("%d ", a[i][j]);
}
printf("\n");
}
printf("\n");
printf("矩陣轉置后:\n");
for(i = 0; i < 3; i++)
{
for(j = 0; j < 3; j++)
{
printf("%d ", b[i][j]);
}
printf("\n");
}
getchar();
return 0;
}
1.8 二維數組一般應用在哪里?
與矩陣有關的運算
2.本周的內容,你還不會什么?
詳細羅列不明白地方,包括課堂派錯題、PTA錯題。
- 課堂派:
D選項錯誤:初始化列表的元素數目超過數組長度
B選項中\x是輸出16進制的標識
- 期中考:
1.static有什么作用
一、定義全局靜態變量 :在全局變量前面加上關鍵字static,該全局變量變成了全局靜態變量。全局靜態變量有以下特點:
(1)在全局數據區內分配內存
(2) 如果沒有初始化,其默認值為0
(3)該變量在本文件內從定義開始到文件結束可見
二、定義局部靜態變量:在局部靜態變量前面加上關鍵字static,該局部變量便成了靜態局部變量。靜態局部變量有以下特點:
(1)該變量在全局數據區分配內存
(2) 如果不顯示初始化,那么將被隱式初始化為0
(3) 它始終駐留在全局數據區,直到程序運行結束
(4)其作用域為局部作用域,當定義它的函數或語句塊結束時,其作用域隨之結束。