作業要求一
PTA作業的提交列表
第一次作業
第二次作業
第三次作業
作業要求二
題目1.刪除字符串中數字字符(函數題)
1.設計思路
- (1)算法
第一步:調用定義的函數。
第二步:定義i=0、j=0,i為原字符數組角標,j為刪除后字符數組角標。使用循環語句讀取字符數組元素,當字符數組元素為數字字符'0'~'9'時不進行操作,當字符數組元素為其它字符元素時,吧s[i]賦值給s[j],並讓j加一。當s[i]為結束字符'\0'時,循環結束,並添加結束字符。
第三步:結果返回主函數。
- (2)流程圖
2.實驗代碼
void delnum(char *s)
{
int i,j;
for(i = 0, j = 0; s[i] != '\0'; i++)
{
if (!s[i] >= '0' && s[i] <= '9')
{
s[j] = s[i];
j++;
}
}
s[j] = '\0';
return;
}
完整代碼
#include <stdio.h>
void delnum(char *s);
int main ()
{
char item[80];
gets(item);
delnum(item);
printf("%s\n",item);
return 0;
}
void delnum(char *s)
{
int i,j;
for(i = 0, j = 0; s[i] != '\0'; i++)
{
if (!s[i] >= '0' && s[i] <= '9')
{
s[j] = s[i];
j++;
}
}
s[j] = '\0';
return;
}
3.本題調試過程碰到問題及解決辦法
本題未遇到問題。
題目2.統計子串在母串出現的次數
1.設計思路
- (1)算法
第一步:調用定義的函數。
第二步:定義i、j、n,使用雙重循環結構,外層循環用來遍歷數組元素,內層循環判斷字符數組元素是否相等,完全相等時,可遍歷子串,則次數加一。
第三步:結果返回主函數。
- (2)流程圖:略。
2.實驗代碼
int fun(char *str,char *substr)
{
int i,j,n=0;
for(i = 0; *(str+i) != '\0'; i++)
{
int a=0;
for(j = 0, a = i; *(str+a) == *(substr+j); j++, a++)
{
if(*(substr+j+1) == '\0')
n++;
}
}
return n;
}
完整代碼
#include<stdio.h>
int fun(char *str,char *substr);
int main()
{
//char str[81]="asdasasdfgasdaszx67asdmklo",substr[4]="asd";
char str[81],substr[4];
gets(str);
gets(substr);
int n;
n=fun(str,substr);
printf("n=%d\n",n);
return 0;
}
int fun(char *str,char *substr)
{
int i,j,n=0;
for(i = 0; *(str+i) != '\0'; i++)
{
int a=0;
for(j = 0, a = i; *(str+a) == *(substr+j); j++, a++)
{
if(*(substr+j+1) == '\0')
n++;
}
}
return n;
}
3.本題調試過程碰到問題及解決辦法
解題沒有什么錯誤,但是我自己有兩個小問題。
(1)當我寫完代碼后,發現自己解題並沒有使用指針的思想,於是想嘗試重新用指針的方式解題,但是卻沒有什么好的思路,最多就是將a[i]和*(a+i)進行替換,所以我現在還是不能較好的使用指針。
(2)PTA題目所給出的主函數只能應用於題目所給出的案例,不好驗證代碼的正確性,所以我將主函數內直接給出的字符串改成輸入進行運行調試。
題目3.字符串中除首尾字符外的其余字符按降序排列
1.設計思路
- (1)算法
第一步:調用定義的函數。
第二步:定義i、j,使用雙重循環結構,外層循環用來遍歷字符串中除首尾字符外的其余字符,內層循環判斷字符數組元素大小(選擇排序法)。
第三步:結果返回主函數。
- (2)流程圖:略。
2.實驗代碼
int fun(char *s,int num)
{
int i,j;
for(i = 1; *(s+i+2) != '\0'; i++)
{
for(j = i; *(s+j+2) != '\0'; j++)
{
if(*(s+i) < *(s+j+1))
{
int t;
t = *(s+i);
*(s+i) = *(s+j+1);
*(s+j+1) = t;
}
}
}
return *s;
}
完整代碼
#include <stdio.h>
int fun(char *s,int num);
int main()
{
char s[10];
gets(s);
fun(s,10);
printf("%s",s);
return 0;
}
int fun(char *s,int num)
{
int i,j;
for(i = 1; *(s+i+2) != '\0'; i++)
{
for(j = i; *(s+j+2) != '\0'; j++)
{
if(*(s+i) < *(s+j+1))
{
int t;
t = *(s+i);
*(s+i) = *(s+j+1);
*(s+j+1) = t;
}
}
}
return *s;
}
3.本題調試過程碰到問題及解決辦法
同上一題,PTA題目所給出的主函數可應用范圍很小。
題目4. 輸出學生成績
1.設計思路
- (1)算法
第一步:定義所需變量,輸入學生人數。
第二步:使用動態內存分配語句。
第三步:使用循環結構,對學生成績進行輸入,並計算平均成績。使用冒泡排序法,將成績從大到小排列。
第四步:輸出結果。
- (2)流程圖:略
2.實驗代碼
#include<stdio.h>
int main()
{
int N, a[N];
float sum, average;
scanf("%d",&N);
if ((a[N] = (float *)malloc(N*sizeof(float))) == NULL)
{
printf("Not able to allocate memory. \n");
exit (1);
}
int i, j, k;
for(i = 0; i < N; i++)
{
scanf("%d",&a[i]);
sum = sum + a[i];
}
average = sum / N;
for(j = 0; j < N - 1; j++)
{
for(k = 0; k < N - 1 - j; k++)
{
int t = 0;
if(a[k] > a[k+1])
{
t = a[k];
a[k] = a[k+1];
a[k+1] = t;
}
}
}
printf("average = %.2f\nmax = %.2f\nmin = %.2f",average,(float)a[N-1],(float)a[0]);
return 0;
}
3.本題調試過程碰到問題及解決辦法
第一次提交未使用動態內存分配,不過提交通過了,之后經提醒添加使用了動態內存分配語句。
題目5. 計算職工工資
1.設計思路
- (1)算法
第一步:定義結構體變量,成員包括——姓名、基本工資、浮動工資、支出和實發工資。
第二步:輸入人數n,引用結構體變量。
第三步:使用循環結構,輸入姓名、基本工資、浮動工資、支出,計算實發工資,並輸出姓名和實發工資。
- (2)流程圖
2.實驗代碼
#include<stdio.h>
struct clerk
{
char name[10];
float wages, floating, pay, wage;
}c1;
int main()
{
int n, i;
scanf("%d",&n);
struct clerk c[n];
for(i = 0; i < n; i++)
{
scanf("%s %f %f %f",c[i].name, &c[i].wages, &c[i].floating, &c[i].pay);
c[i].wage = c[i].wages + c[i].floating - c[i].pay;
printf("%s %.2f\n",c[i].name, c[i].wage);
}
}
3.本題調試過程碰到問題及解決辦法
無。
題目6. 計算平均成績
1.設計思路
- (1)算法
第一步:定義結構變量,成員包括——學號、姓名和成績。
第二步:輸入人數N,引用結構體變量。
第三步:使用循環結構,輸入學號、姓名和成績,計算總成績。
第四步:計算平均成績並輸出。
第五步:使用循環結構,選擇成績低於平均的並輸出。
- (2)流程圖:略。
2.實驗代碼
#include<stdio.h>
struct student
{
char id[6], name[10];
int achievement;
}s1;
int main()
{
int N, i;
double sum = 0, average = 0;
scanf("%d",&N);
struct student s[N];
for(i = 0; i < N; i++)
{
scanf("%s %s %d",s[i].id,s[i].name,&s[i].achievement);
sum = s[i].achievement + sum;
}
average = sum / N;
printf("%.2f\n",average);
for(i = 0; i < N; i++)
{
if(s[i].achievement < average)
printf("%s %s\n",s[i].name,s[i].id);
}
}
3.本題調試過程碰到問題及解決辦法
本題出現了一個小錯誤,輸入時成績沒有加“&”符號,導致程序無法運行。要時刻保持認真的態度,不要犯這樣的錯誤。
題目7.按等級統計學生成績(函數題)
1.設計思路
- (1)算法
第一步:調用定義函數。
第二步:使用循環結構,循環判斷每個學生的等級,N為不及格人數,當學生為D等級時,N加一。
第三步:結果返回主函數。
- (2)流程圖
2.實驗代碼
int set_grade( struct student *p, int n )
{
int i,N = 0;
for(i = 0; i < n; i++)
{
if((p+i)->score <= 100 && (p+i)->score >= 85)
(p+i)->grade = 'A';
else if((p+i)->score <= 84 && (p+i)->score >= 70)
(p+i)->grade = 'B';
else if((p+i)->score <= 69 && (p+i)->score >= 60)
(p+i)->grade = 'C';
else if((p+i)->score <= 59 && (p+i)->score >= 0)
{
(p+i)->grade = 'D';
N++;
}
}
return N;
}
完整代碼
#include <stdio.h>
#define MAXN 10
struct student{
int num;
char name[20];
int score;
char grade;
};
int set_grade( struct student *p, int n );
int main()
{ struct student stu[MAXN], *ptr;
int n, i, count;
ptr = stu;
scanf("%d\n", &n);
for(i = 0; i < n; i++)
scanf("%d%s%d", &stu[i].num, stu[i].name, &stu[i].score);
count = set_grade(ptr, n);
printf("The count for failed (<60): %d\n", count);
printf("The grades:\n");
for(i = 0; i < n; i++)
printf("%d %s %c\n", stu[i].num, stu[i].name, stu[i].grade);
return 0;
}
int set_grade( struct student *p, int n )
{
int i,N = 0;
for(i = 0; i < n; i++)
{
if((p+i)->score <= 100 && (p+i)->score >= 85)
(p+i)->grade = 'A';
else if((p+i)->score <= 84 && (p+i)->score >= 70)
(p+i)->grade = 'B';
else if((p+i)->score <= 69 && (p+i)->score >= 60)
(p+i)->grade = 'C';
else if((p+i)->score <= 59 && (p+i)->score >= 0)
{
(p+i)->grade = 'D';
N++;
}
}
return N;
}
3.本題調試過程碰到問題及解決辦法
錯誤一:本題出現了編譯錯誤,后發現我將題目中完整代碼進行了提交。
錯誤二:本次有測試點出現錯誤,錯誤提示為warning: ignoring return value of ‘scanf’。
解決方法:使用原輸入值n對循環進行判斷,問題解決。
題目8.結構體數組按總分排序(函數題)
1.設計思路
- (1)算法
第一步:調用calc函數,使用雙重循環結構,內層循環通過循環計算單個學生總成績,外層循環通過循環改變學生。
第二步:調用sort函數,通過對sum的比較使用冒泡排序法對學生進行排序。
- (2)流程圖:略。
2.實驗代碼
void calc(struct student *p,int n)
{
int i, j;
for(i = 0; i < n; i++)
{
for(j = 0; j < 3; j++)
{
p->sum = p->score[j] + p->sum;
}
p++;
}
}
void sort(struct student *p,int n)
{
int i, j;
struct student t;
for(i = 1; i < n; i++)
for(j = 0; j < n - i; j++)
if(p[j].sum < p[j+1].sum){
t = p[j];
p[j] = p[j+1];
p[j+1] = t;
}
}
完整代碼
#include <stdio.h>
struct student
{
int num;
char name[15];
float score[3];
float sum;
};
void calc(struct student *p,int n);
void sort(struct student *p,int n);
int main()
{
struct student stu[5];
int i,j;
float f;
for(i=0;i<5;i++)
{
scanf("%d%s",&stu[i].num,stu[i].name);
for(j=0;j<3;j++)
{
scanf("%f",&f);
stu[i].score[j]=f;
}
}
calc(stu,5);
sort(stu,5);
for(i=0;i<5;i++)
{
printf("%5d%15s",stu[i].num,stu[i].name);
printf(" %.1f %.1f %.1f %.1f\n",stu[i].score[0],stu[i].score[1],stu[i].score[2], stu[i].sum);
}
return 0;
}
void calc(struct student *p,int n)
{
int i, j;
for(i = 0; i < n; i++)
{
for(j = 0; j < 3; j++)
{
p->sum = p->score[j] + p->sum;
}
p++;
}
}
void sort(struct student *p,int n)
{
int i, j;
struct student t;
for(i = 1; i < n; i++)
for(j = 0; j < n - i; j++)
if(p[j].sum < p[j+1].sum){
t = p[j];
p[j] = p[j+1];
p[j+1] = t;
}
}
3.本題調試過程碰到問題及解決辦法
本題在void函數中添加了返回語句,刪除即可解決問題。
作業要求三
1、學習總結
所學知識點:對指針的復習,動態內存分配,定義結構體變量及結構體變量的引用,以及數組、指針、結構的結合使用。
有關動態內存的分配,老師講述較為簡單,不過網上有很多相關資料,在這里分享一篇我找到的較為詳盡的文章:《C語言中手把手教你動態內存分配》。
存在問題:不能較好的使用指針。
2、我的Git地址
3、點評鏈接(待添加)
鏈接一
鏈接二
鏈接三
4、圖表