作業要求一 :
PTA作業的提交列表:
作業要求二:
6-1 輸出月份英文名
1.設計思路
(1)主要描述算法:
第一步:本題要求通過字符串指針實現函數,可以返回一個給定月份的英文名稱。
第二步:定義整形變量n,通過switch語句,判斷每一條語句,如果是就按數字輸出月份,否則執行default,輸出NULL
第三步:按要求返回主函數並輸出。
(2)流程圖:
主函數:
調用函數:
2.實驗代碼:
char *getmonth( int n ) { switch(n) { case 1:return "January"; case 2:return "February"; case 3:return "March"; case 4:return "April"; case 5:return "May"; case 6:return "June"; case 7:return "July"; case 8:return "August"; case 9:return "September"; case 10:return "October"; case 11:return "November"; case 12:return "December"; default:return NULL; } }
3.本題調試過程碰到問題及解決辦法
遇到的問題1:應該返回的是指針,而不是字符串。
改正方法:將printf改成return
遇到的問題2:case后面的數字用單引號括了起來。
改正方法:case后面可以是數字,因為switch后面是整形,所以不用單引號。(通過查找課本105頁得到答案)
6-2 查找星期
1.設計思路
主要描述算法:
第一步:本題要求用指針數組實現函數,可以根據下表查找到星期,返回對應的序號。
第二步:首先定義一個指針數組,將星期都存到數組里,通過for循環語句和if條件判斷(strcmp)比較星期是否相同,break回到上一級,否則返回m。
第三步:按要求輸出序號和星期或-1
2.實驗代碼:
int getindex( char *s ) { int i,m=-1; char *week[7]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"}; for(i=0;i<7;i++) { if (strcmp (s, week[i]) == 0) { m=i; break; } } return m; }
3.本題調試過程碰到問題及解決辦法
遇到的問題:本題要求傳遞的應該是字符串,所以不能用switch語句
改正方法:用上課講的指針數組的方式。
遇到的問題2:在循環中沒有先定義m=-1所以總是出現部分正確。
改正方法:先把m=-1定義在前面,再將其賦給i,就不會出現部分正確了。
6-3 計算最長的字符串長度
1.設計思路
主要描述算法:
第一步:本題要求實現一個函數,用於計算有n個元素的指針數組s中最長的字符串的長度
第二步:首先定義整形變量和字符指針數組m,通過兩個for循環判斷,*(*(s+i)+j)!='\0',繼續執行;在第二個for循環中判斷如果m[i]>count,輸出最長的長度,否則繼續循環
第三步:輸出指針數組中最長字符串的長度。
2.實驗代碼:
int max_len( char *s[], int n ) { int i,j,m[20]={0}; int count=0; for(i=0;i<n;i++) { for(j=0;*(*(s+i)+j)!='\0';j++) { } m[i]=j; } for(i=0;i<n;i++) { if(m[i]>count) { count=m[i]; } } return count; }
3.本題調試過程碰到問題及解決辦法
遇到的問題:指針*(*(s+i)+j)!='\0'弄錯了
改正方法:應該是用指針的指針來判斷。
6-4 指定位置輸出字符串
1.設計思路
主要描述算法:
第一步:本題要求編寫實現函數實現對給定的一個字符串和兩個字符,打印出給定字符串中從與第一個字符匹配的位置開始到與第二個字符匹配的位置之間的所有字符
第二步:首先定義整形變量,通過一個for循環先將ch1的值賦給*(s+i);定義指針,判斷(*(s+j)!=ch2)&&(*(s+j)!='\0'),如果*(s+j)!='\0',輸出,否則返回a
第三步:在大的for循環后輸出,再返回s+i的值。
2.實驗代碼:
char *match( char *s, char ch1, char ch2 ){ int i,j; for(i=0;*(s+i)!='\0';i++) { if(*(s+i)==ch1) { char *a= &s[i]; for(j=i;(*(s+j)!=ch2)&&(*(s+j)!='\0');j++) { printf("%c",*(s+j)); } if(*(s+j)!='\0') printf("%c",*(s+j)); printf("\n"); return a; } } printf("\n"); return s+i; }
3.本題調試過程碰到問題及解決辦法
遇到的問題:%c輸出的應該是指針*(s+i),而不是s+i
改正方法:將s+i改成*(s+i),程序運行成功。
6-1 奇數值結點鏈表
1.設計思路
主要描述算法:
第一步:本題要求實現兩個函數,分別將讀入的數據存儲為單鏈表、將鏈表中奇數值的結點重新組成一個新的鏈表。
第二步:在readlist函數中,將輸入的值存儲在鏈表里;在while循環內對p進行動態分配內存;當末尾結點的next為空,最后返回鏈表的頭結點。
第三步:根據題目要求的條件對鏈表結點中date的值進行分類判斷,最后按照要求返回要求鏈表的頭結點。
(2)流程圖:
調用函數:
調用函數:
調用函數:
2.實驗代碼:
struct ListNode *readlist() { int number; struct ListNode *p = NULL,*head = NULL,*tail = NULL; scanf("%d",&number); while(number!=-1 && number>0 ) { p = (struct ListNode*)malloc(sizeof(struct ListNode)); p->data = number; if(head == NULL) { head = p; } else { tail->next = p; } tail = p; scanf("%d",&number); } if(head == NULL) { return NULL; } tail->next = NULL; return head; } struct ListNode *getodd( struct ListNode **L ) { struct ListNode *p = *L,*head1 = NULL,*r = NULL,*L1 = NULL,*r1 = NULL; while(p!=NULL && p->data>0) { if(p->data%2!=0) { if(head1 == NULL) { head1 = p; } else { r->next = p; } r = p; } else { if(L1 ==NULL) { L1 = p; } else { r1->next = p; } r1 = p; } p = p->next; } if(head1==NULL) { return NULL; } else { r->next = NULL; } if(L1==NULL) { *L = NULL; } else { r1->next = NULL; *L = L1; } return head1; }
3.本題調試過程碰到問題及解決辦法
遇到的問題:在p進行動態分配,開辟新單元的時候,在*后面加了p=L.
改正方法:*號后面應該什么都不加。
6-2 學生成績鏈表處理
1.設計思路
主要描述算法:
第一步:本題要求實現兩個函數,一個將輸入的學生成績組織成單向鏈表;另一個將成績低於某分數線的學生結點從鏈表中刪除。
第二步:在createlist函數中將輸入的學號,姓名和分數存儲到鏈表中;當判斷學號不為0的情況下輸入姓名和成績,返回鏈表的頭結點。
第三步:在deletelist函數中遍歷鏈表的結點,判斷后鏈表的頭結點返回主函數。
2.實驗代碼:
struct stud_node *createlist() { int num,score; char name[20]; struct stud_node *p,*head=NULL,*tail=NULL; p = (struct stud_node*)malloc(sizeof(struct stud_node)); scanf("%d",&num); while (num != 0) { p = (struct stud_node *)malloc (sizeof (struct stud_node)); scanf ("%s %d", p->name, &p->score); p->num=num; if (head == NULL) head = p; else tail->next = p; tail = p; scanf ("%d", &num); } return head; } struct stud_node *deletelist( struct stud_node *head, int min_score ) { struct stud_node *L=head,*head1=NULL,*tail1=NULL; while(L!=NULL) { if(L->score>=min_score) { if(head1==NULL) { head1 = L; } else { tail1->next = L; } tail1 = L; } L=L->next; } if(head1==NULL) { return NULL; } else { tail1->next =NULL; } return head1; }
3.本題調試過程碰到問題及解決辦法
遇到的問題:p->num賦值,判斷錯了
改正方法:應該將num的值賦給p->num.
6-3 鏈表拼接
1.設計思路
主要描述算法:
第一步:本題要求實現一個合並兩個有序鏈表的簡單函數。
第二步:對本題的理解不是很清楚,就在網上找到相應的類似的題目。大致理解了一下。
第三步:將兩個帶頭結點的鏈表進行連接,連接后的鏈表仍然使用原來的存儲空間,找到第一個鏈表的尾節點,使其指針域指向下一個鏈表的頭結點
2.實驗代碼:
struct ListNode *mergelists(struct ListNode *list1, struct ListNode *list2) { int num = 0; int temp[100]; struct ListNode *p = list1; while(p != NULL) { temp[num] = p->data; num++; p = p->next; } p = list2; while(p != NULL) { temp[num] = p->data; num++; p = p->next; } int i,j; for(i = 0; i < num; i++) for(j = i + 1; j < num; j++) { if(temp[i] > temp[j]) { int t; t = temp[i]; temp[i] = temp[j]; temp[j] = t; } } struct ListNode *newlist = NULL; struct ListNode *endlist = NULL; struct ListNode *q; for(i = 0; i < num; i++) { q = (struct ListNode *)malloc(sizeof(struct ListNode)); q->data = temp[i]; if(newlist == NULL) { newlist = q; newlist->next = NULL; } if(endlist != NULL) { endlist->next = q; } endlist = q; endlist->next = NULL; } return newlist; }
3.本題調試過程碰到問題及解決辦法
遇到的問題:用之前的方法行不通,就到網上找了題目
改正方法:在網上找到解題思路。
要求三、學習總結和進度:
學習總結:
1、總結兩周里所學的知識點,回答下列問題?(用自己的話表達出你的理解,網上復制粘貼沒有分數)(5分)
(1)如何理解指針數組,它與指針、數組有何關系?為何可以用二級指針對指針數組進行操作?
指針數組是指向內存地址的數組,使用指針數組更節省空間;二維數組定義存在數據區(可更改)
(2)將C高級第三次PTA作業(1)任何一個題目改為使用二級指針對指針數組進行操作。
目前對這一部分的內容掌握得不是很好。
(3)用指針數組處理多個字符串有何優勢?可以直接輸入多個字符串給未初始化的指針數組嗎?為什么?
使用指針數組處理多個字符串更節省空間,因為每個字符串是單獨存放的;不可以,未初始化,會出現一些錯誤;
git的地址:https://git.coding.net/Aspirer1/c3.git
點評同學:
孫銘婧:http://www.cnblogs.com/sun031915/p/8836088.html
張心悅:http://www.cnblogs.com/zxy980612/p/8858885.html
吳曉明:http://www.cnblogs.com/gu-an-cheng-wxm/p/8903685.html
進度表: