C语言课程设计报告-------学生成绩简单管理
程序一、系统菜单的主要功能(1)输入若干条记录(2)显示所有记录(3)按学号排序(4)插入一条记录(5)按姓名查找,删除一条记录(6)查找并显示一条记录(7)输出统计信息 (新增)(8)从正文中添加数据到结构体
数组中(9)将所有数据写入
文件中(0)退出程序二、题岩态目分析该题主要考察学生对结构体,指针,文件的 *** 作,以及C语言算法的掌握,所以完成此道题目要求较强的设计能力,尤其是要有一种大局观的意识。如何调程序也非常重要,通过这个程序可以学习到以前调试短程序没有的的经验。菜单中的每一个选项都对应一个子程序,子程序的算法几乎囊获了所有C语言学过的技巧,下面就各个子程序中的功能进行说明:功能1和4的算法相似,输入一条记录到结构体中去,其中有一部很关键,就是通过gets将所有的多余的字符,回车读去,否则就会出错。功能2是显示所有的记录,通过循环输出,格式也比较重要。功能3为按学号排序,因为学号定义成了字符数组的形式,因此在运用冒泡法进行排序的时候,要用到strcmp,strcpy等函数。功能5为氏贺按姓名删除记录,先输入姓名,再一一比较,如果没有则返回失败信息,如果找到就将此记录都向前移一位,返回n-1。功能6的算法在5中就已经体现了,输入姓名,一一比较。功能7为新增的功能,因为考虑到原来给出的函数中竟然没有对学生成绩的统计功能,因此新增此功能,可以得出所有的记录个数,最高、最低、平均分,并输出相关的学生信息等。功能8和9是对文件的 *** 作,提前准备好数据。三、程序正文部分#include<stdio.h>/*引用库函数*/#include<stdlib.h>#include<ctype.h>#include<string.h>typedef struct /*定义结构体数组*/{char num[10]/*学号*/char name[20]/*姓名*/int score/*成绩*/}StudentStudent stu[80]/*结构体数组变量*/int menu_select() /*菜单函数*/{char cdo{system("cls")/*运行前清屏*/printf("\t\t****Students' Grade Management System****\n")/*菜单选择*/printf("\t\t | 1. Input Records |\n")printf("\t\t | 2. Display All Records |\n")printf("\t\t | 3. Sort |\n")printf("\t\t | 4. Insert a Record |\n")printf("\t\t | 5. Delete a Record |\n")printf("\t\t | 6. Query |\n")printf("\t\t | 7. Statistic |\n")printf("\t\t | 8. Add Records from a Text File|\n")printf("\t\t | 9. Write to a Text file |\n")printf("\t\t | 0. Quit |\n")printf("\t\t*****************************************\n")printf("\t\t\tGive your Choice(0-9):")c=getchar()/*读入选择*/}while(c<'0'||c>'9')return(c-'0')/*返回歼枣派选择*/}int Input(Student stud[],int n) /*输入若干条记录*/{int i=0char sign,x[10]/*x[10]为清除多余的数据所用*/while(sign!='n'&&sign!='N') /*判断*/{ printf("\t\t\tstudent's num:")/*交互输入*/scanf("\t\t\t%s",stud[n+i].num)printf("\t\t\tstudent's name:")scanf("\t\t\t%s",stud[n+i].name)printf("\t\t\tstudent's score:")scanf("\t\t\t%d",&stud[n+i].score)gets(x)/*清除多余的输入*/printf("\t\t\tany more records?(Y/N)")scanf("\t\t\t%c",&sign)/*输入判断*/i++}return(n+i)}void Display(Student stud[],int n) /*显示所有记录*/{int iprintf("\t\t\t-----------------------------------\n")/*格式头*/printf("\t\t\tnumber name score\n")printf("\t\t\t-----------------------------------\n")for(i=1i<n+1i++) /*循环输入*/{printf("\t\t\t%-16s%-15s%d\n",stud[i-1].num,stud[i-1].name,stud[i-1].score)if(i>1&&i%10==0) /*每十个暂停*/{printf("\t\t\t-----------------------------------\n")/*格式*/printf("\t\t\t")system("pause")printf("\t\t\t-----------------------------------\n")}}printf("\t\t\t")system("pause")}void Sort_by_num(Student stud[],int n) /*按学号排序*/{ int i,j,*p,*q,schar t[10]for(i=0i<n-1i++) /*冒泡法排序*/for(j=0j<n-1-ij++)if(strcmp(stud[j].num,stud[j+1].num)>0){strcpy(t,stud[j+1].num)strcpy(stud[j+1].num,stud[j].num)strcpy(stud[j].num,t)strcpy(t,stud[j+1].name)strcpy(stud[j+1].name,stud[j].name)strcpy(stud[j].name,t)p=&stud[j+1].scoreq=&stud[j].scores=*p*p=*q*q=s}}int Insert_a_record(Student stud[],int n) /*插入一条记录*/{char x[10]/*清除多余输入所用*/printf("\t\t\tstudent's num:")/*交互式输入*/scanf("\t\t\t%s",stud[n].num)printf("\t\t\tstudent's name:")scanf("\t\t\t%s",stud[n].name)printf("\t\t\tstudent's score:")scanf("\t\t\t%d",&stud[n].score)gets(x)n++Sort_by_num(stud,n)/*调用排序函数*/printf("\t\t\tInsert Successed!\n")/*返回成功信息*/return(n)}int Delete_a_record(Student stud[],int n) /*按姓名查找,删除一条记录*/{ char s[20]int i=0,jprintf("\t\t\ttell me his(her) name:")/*交互式问寻*/scanf("%s",s)while(strcmp(stud[i].name,s)!=0&&i<n) i++/*查找判断*/if(i==n){ printf("\t\t\tnot find!\n")/*返回失败信息*/return(n)}for(j=ij<n-1j++) /*删除 *** 作*/{strcpy(stud[j].num,stud[j+1].num)strcpy(stud[j].name,stud[j+1].name)stud[j].score=stud[j+1].score}printf("\t\t\tDelete Successed!\n")/*返回成功信息*/return(n-1)}void Query_a_record(Student stud[],int n) /*查找并显示一个记录*/{ char s[20]int i=0printf("\t\t\tinput his(her) name:")/*交互式输入*/scanf("\t\t\t%s",s)while(strcmp(stud[i].name,s)!=0&&i<n) i++/*查找判断*/if(i==n){ printf("\t\t\tnot find!\n")/*输入失败信息*/return}printf("\t\t\this(her) number:%s\n",stud[i].num)/*输出该学生信息*/printf("\t\t\this(her) score:%d\n",stud[i].score)}void Statistic(Student stud[],int n) /*新增功能,输出统计信息*/{ int i,j=0,k=0,sum=0float aver/*成绩平均值*/for(i=0i<ni++) /*循环输入判断*/{sum+=stud[i].scoreif(stud[j].score>stud[i].score) j=iif(stud[k].score<stud[i].score) k=i}aver=1.0*sum/nprintf("\t\t\tthere are %d records.\n",n)/*总共记录数*/printf("\t\t\tthe hignest score:\n")/*最高分*/printf("\t\t\tnumber:%s name:%s score:%d\n",stud[j].num,stud[j].name,stud[j].score)printf("\t\t\tthe lowest score:\n")/*最低分*/printf("\t\t\tnumber:%s name:%s score:%d\n",stud[k].num,stud[k].name,stud[k].score)printf("\t\t\tthe average score is %5.2f\n",aver)/*平均分*/}int AddfromText(Student stud[],int n) /*从文件中读入数据*/{ int i=0,numFILE *fp/*定义文件指针*/char filename[20]/*定义文件名*/printf("\t\t\tInput the filename:")scanf("\t\t\t%s",filename)/*输入文件名*/if((fp=fopen(filename,"rb"))==NULL) /*打开文件*/{ printf("\t\t\tcann't open the file\n")/*打开失败信息*/printf("\t\t\t")system("pause")return(n)}fscanf(fp,"%d",&num)/*读入总记录量*/while(i<num) /*循环读入数据*/{fscanf(fp,"%s%s%d",stud[n+i].num,stud[n+i].name,&stud[n+i].score)i++}n+=numfclose(fp)/*关闭文件*/printf("\t\t\tSuccessed!\n")printf("\t\t\t")system("pause")return(n)}void WritetoText(Student stud[],int n) /*将所有记录写入文件*/{int i=0FILE *fp/*定义文件指针*/char filename[20]/*定义文件名*/printf("\t\t\tWrite Records to a Text File\n")/*输入文件名*/printf("\t\t\tInput the filename:")scanf("\t\t\t%s",filename)if((fp=fopen(filename,"w"))==NULL) /*打开文件*/{printf("\t\t\tcann't open the file\n")system("pause")return}fprintf(fp,"%d\n",n)/*循环写入数据*/while(i<n){fprintf(fp,"%-16s%-15s%d\n",stud[i].num,stud[i].name,stud[i].score)i++}fclose(fp)/*关闭文件*/printf("Successed!\n")/*返回成功信息*/}void main() /*主函数*/{int n=0for(){switch(menu_select()) /*选择判断*/{case 1:printf("\t\t\tInput Records\n")/*输入若干条记录*/n=Input(stu,n)breakcase 2:printf("\t\t\tDisplay All Records\n")/*显示所有记录*/Display(stu,n)breakcase 3:printf("\t\t\tSort\n")Sort_by_num(stu,n)/*按学号排序*/printf("\t\t\tSort Suceessed!\n")printf("\t\t\t")system("pause")breakcase 4:printf("\t\t\tInsert a Record\n")n=Insert_a_record(stu,n)/*插入一条记录*/printf("\t\t\t")system("pause")breakcase 5:printf("\t\t\tDelete a Record\n")n=Delete_a_record(stu,n)/*按姓名查找,删除一条记录*/printf("\t\t\t")system("pause")breakcase 6:printf("\t\t\tQuery\n")Query_a_record(stu,n)/*查找并显示一个记录*/printf("\t\t\t")system("pause")breakcase 7:printf("\t\t\tStatistic\n")Statistic(stu,n)/*新增功能,输出统计信息*/printf("\t\t\t")system("pause")breakcase 8:printf("\t\t\tAdd Records from a Text File\n")n=AddfromText(stu,n)/*新增功能,输出统计信息*/breakcase 9:printf("\t\t\tWrite to a Text file\n")WritetoText(stu,n)/*循环写入数据*/printf("\t\t\t")system("pause")breakcase 0:printf("\t\t\tHave a Good Luck,Bye-bye!\n")/*结束程序*/printf("\t\t\t")system("pause")exit(0)}}}四、函数调用关系图注:“→”代表调用Input函数打印链表记录Display函数输入若干条记录menu_select()函数选择菜单Sort_by_num函数显示所有记录Delete_a_record函数按姓名查找,删除一条记录Query_a_record查找并显示一条记录Statistic函数输出统计信息 (新增)AddfromText函数从正文中添加数据到结构体数组中Main函数Insert_a_record插入一条记录WritetoText函数 将所有数据写入文件中退出程序Reverse(head)函数按学号排序五、设计测试流程1、进入界面2、输入选项1,回车;按提示输入数据:3、回到主菜单;输入选项7,回车;输入文件名:data.txt,回车;出现成功提示,则读入文件 *** 作成功。4、回到主菜单,输入2,回车每10个暂停显示数据5、回到主菜单,输入3,回车出现排序成功信息。6、回到主菜单,输入4,回车按提示插入一组数据7、回到主菜单,输入5,回车按提示输入姓名,删除数据出现删除成功的信息8、回到主菜单,输入6,回车输入姓名进行查询9、回到主菜单,输入7,回车出现统计信息10、回到主菜单,输入9,回车输入result.txt,回车出现成功写入文件的信息11、回到主菜单,输入0,回车退出系统 由于自学ks的社会性,为了体现公正和公平,试题不能像本科院校中常见的那样重复使用。自学ks的试卷内容有广泛且分散的特点,这要求考生必须全面地复习教材的内容。
1.单项选择题
试题中的单项选择题中的多数试题涉及整本教材介绍的概念和知识点。为解答这类试题,要求考生要熟练地掌握和熟记大纲中指出的“识记”和“领会”的内容。考生应摘出教材中有关c语言的重要概念、定义、有关语言成分性质的叙述,对它们深入的理解和熟记,并对语言的一些基本规定能作简单的应用。清考生注意,理解、熟记和大段地背诵的区别。由于考题表现形式的多样性,理解是最重要的,仅对关键性的概念才有准确熟记的必要,多数的概念因是理解,并要求能熟练应用。试题通常要求对某个概念、术语或计算结果作出判断,或对一些规定作简单的应用等。由于计算机科学是一门新兴学科,许多概念还没有唯一性的定义,不同书籍由于出发点或论述领域不同,同一概念会有不同的说法,为此考生在复习迎考时,不要脱离指定自学ks教材,而从其它教材出发进行复习。
「例1」设有以下代码定义字符数组c和字符指针变量pc:
char c[10]=“abed”,*pc=c;
问*(pc+4)的值。供选择的答案有:
①“abcd‘ ②'\0' ③ ' d' ④不能确定
上述代码使字符数组c的前5个元素依次为:c[0]=‘a’c[1]=‘b’, c[2]=‘c’, c[3]= ‘d',c[4]=’\0‘。初始化pc=c使字符指针变量pc指向c数组的首元素c[0].而表达式pc+4的值是c[4]的指针。因此,表达式*(pc+4)就是引用c[4].所以问题的解答为②。
「例2」指出下列说法中错误的叙述。
①构成数组的所有元素的数据类型必须是相同的
②用指针法引用数组元素允许数组元素的下标越界
③一维数组元素的下标为1,2,3,……
④定义数组时的长度可以是整型常量表达式
由数组的概念知,数组的全部元素有相同的数据类型,另在定义数组时,需指出数组的元素个数,指定数组元素个数的表达式必须在编译时可计算的,即只允许是常量表达式,不可以含有变量。所以①和④是正确的叙述,不是问题要求的解答。在c语言中,当指针指向辩好肆数组的某元素(不一定是数组的首元素)时,可利用该指针加减一个携轿整表达式,构成指针表达式指向数组的某元素,然后用取内容运算符。间接引用指针表达式所指的数组元素。如有代码:
int a[100],* p;
表达式p=&a「20]使p指向a[20],,通过p引用数组a[l],可用表达式*(p-19)。由c语言的约定,当指针指向数组某元素时,用指针表达式引用它所指的数组的某元素也可写成等价的下标引用形式,如表达式*(p-9)可以等价地写成p[-19].这里-19是一个负整数,所以叙述②也是一个正确叙述。这种表示方法是借用下标表示法,与指针加减的整表达式引用数组元素,其中加减的整数实际不是数组元素的下标。还需要指出一点,指针与整表达式和的新指针不应该指向数组之外的别的地址。如前述的例子中指针变量p指向a[20],表达式*(p+n)中的 n要求不能小于 20,也不能大于 79.最后,c语言规定数组元素的下标从0开始顺序编号,所以选择③才是错误的叙述。
2.填充题
填充题要考核的内容与选择题的考核内容基本相同,但考核的形式不同。填充题的试题多数是从基本概念儿语言关于数据类型、程序对象、程序结构等的规定、c程序设计基本技巧等引伸的具体应用。如c语言规定每个字符占一个字节,每个字符串除存储它所包含的字符外,在字符串最后一个字符之后还存有一个字符串结束符。对于这样两个基本概念和规定,填充题可能是问具体的一个字符和一个字符串各占多少个字节等。因填充题是概念或规定的具体应用,解答袜消的难度也就比选择题的要大,不可能有猜得分的机会。
「例3」下列函数的功能是统计并返回形参指针s所指向的字符串所含字符‘a’的个数。试完成程序,写出应填写在程序空框中的代码。
int counts(char *s)
{ int n;
for( n=0;。 ; s++)
if(*s==‘a’)n++;
return n;
}
为统计字符指针s所指字符串包含的某字符的出现次数,必须用一个循环顺序考察整个字符串。由从指针s所指字符串的首字符开始,每考察一个字符后,指针s后移一个字符位置,考察循环直至字符率结束终止。所以填写在空框中的正确代码可写成* s! =‘\ 0’。由于字符串束符‘\ 0’的代码为 8位全0,其值为 0,正确解答也可写成* s!= 0,或更简洁地写成*s.
「例4」在内存中存储‘a’要占用____字节,存储“a”又要占用____字节。
由于c语言规定字符只占1个字节,一个具体的字符当然也只占1个字节。字符串“a”要有1个字节用于存储字符‘a’,另需要1个字节存储字符串的结束符,所以它要占用连续的2个字节。
「例5」设整型变量a、b的值均为3,执行语句:
b= a++, b++, ++a;
后,a的值为____,b的值为____.
该试题的表达式书写形式一般不会直接出现在实际应用程序中,但作为考核考生对有关表达式的计算规则,也不失为是一个很有意义的试题。赋值表达式自右至左计算,而逗号运算符的优先级最低,并且逗号表达式自左至右逐一计算,并以最后子表达式的值为逗号表达式的结果。上述表达式的计算顺序可用以下3个表达式语句等价表示:
b=a++;b++;++a;
由以上一系列表达式知,变量b的最终值与其原来值无关,表达式b= a+十是先计算a++。表达式a+十的值是变量a的原先值3,但又让变量a增1后变为4.然后表达式b++又使变量b增1,变成4.而计算++a的值,是让a增1,使a的值变为5.所以上述表达式使变量a的值变为5,b的值变为4.
如上述表达式改写为:
b+=(a++,b++,++a);
请读者回答执行该表达式后,变量a和b的值又分别为多少。
3.程序分析题
程序分析题要求考生阅读程序,回答程序的输出结果,或指出程序的功能。回答这类问题,要求考生将自己当作一台假想的计算机,模拟执行序。
对于这类试题常有两种可用的方法。一是从程序的初值、循环结构、条件等发现程序的规律厂是完全从模拟执行出发读程序,求出程序的输出结果。如采用后一种方法,由于程序执行的动态性,程序中的有关变量,随着程序的执行,变量的值就会不断变化。一般来说,随时记住全部变量的当前值是非常困难的。一个行之有效的方法是用一个变量表,将程序中的全部变量罗列在该表中,某个变量值的变化记录在该变量当前值的栏中,这样就能方便地列出各个变量的动态变化过程。在这里,考生要当心函数形参及函数的局部变量与实参变量及程序的外部全局变量同名的情况。为了区别它们,对于函数形参和局部变量可以标上它所属的函数名,以与同名的实参变量及外部全局变量相区别。由于试题程序总是完成某种有一定意义的计算工作。一般来说,程序的执行过程舍有某种规律存在。如能找出程序的规律,就不需要逐句阅读程序的语句,能直接导出程序的结果。程序的规律从以下几个方面着手:有关变量的初值,特别是数组的初值;程序的循环控制结构,特别是遍历数组的循环,它的循环控制变量将控制数组元素下标的变化;循环体中的语句的条件,一般条件有两种形式,一种是由数组元素值的大小描述,另一种是由元素的下标值描述,前者用于对其值满足某种条件的元素进行指定的计算,后者用于对满足条件的某些位置上的元素进行指定的计算。
最容易出题,变化也最多的是数组(包括字符串)处理程序,正确解答这类试题要熟练掌握两点:一是引用数组元素的两个等价方法,即用数组首元素指针(数组名)和下标引用数组元素,及通过指向数组元素的指针间接引用数组的元素;二是一些常用的简单算法,如数组或字符串遍历、插入元素或删除元素,以及常用的排序方法等。对于文件处理程序,要注意文件当前的读/写位置,即对于读文件,注意当前读人的数据及前读头位置;对于写文件,要注意当前写入的数据。另外要特别指出的是,通过读程序,能发现程序执行的规律是非常有用的技术。但这个技术的掌握是建立在熟读大量的程序和自己编写过大量程序的基础上的。如一个程序是对数组的前n个元素执行某种 *** 作。考生在阅读这种程序时,不妨假定输入的n值为4或5,将n等于4或5的结果类推到任意的n.
「例6」阅读下列程序,写出程序运行后的输出结果。
# include <stdio.h>
main()
{int a[][3]={1,2,3,4,5,6,7,8,9};
int i,j,s1= 0,s2= 0;
for(i= 0;i<3, i++)
for(j=0;j<3;j++){
if(i==j)sl+=a[i][j];
if(i+j==2) s2+=a[i][j];
}
printf(“sl=%ds2=%d\n”, sl,sz);
}
首先将二维数组a的初值写成每行3个元素,由于程序只提供9个初值,a只有3行:
1 2 3
4 5 6
7 8 9
程序用a[i][j]引用a的元素,所以外循环i是控制行的循环,内循环j是控制列的循环,这两重循环控制遍历整个数组 a的全部元素。条件 i==j表示当行下标与列下标相等时,即是 a的主对角钱上的元素时,将它们累计到变量s1,所以s1的值为15.条件i+j==2用于控制行下标与列下标之和为行列下标之和为某个常数的元素是同在某条右高左低斜线上的元素。对于3行3列的二维数组来说,就是副对角线上的元素。将这些元素累计于变量s2,所以s2的值也是15.
「例7」阅读下列程序,简述程序的主要功能。
main()
{ int i,s[10],*p=&s[9];
for(i=0;i<10;i++) scanf(“%d”,&s[i]);
for(;p>=s;p——) print(“%d”,*p);
printf(“\n );
}
程序中定义的变量i用于循环控制,数组s用于存储读人的整数,指针变量p的初值指向数组s的末元素。程序的第一个循环用于顺序输入数组s的10个元素的情。从程序的第二个循环代码知,每循环一次,指针p减1,即指向数组的前一个元素,循环条件直至循环处理了数组的首元素后结束,循环体只是简单地输出指针当前所指的数组元素。所以该循环实现从数组的末元素开始逆序遍历数组输出。这样程序的功能可简述如下:
“顺序输入10个整数,并逆序输出它们的值。”
4.程序设计题
程序设计题是给出问题,要求考生自己独立编写程序。考生平时认真参加上机实习,自己编写程序,是能解答这类试题的基本条件。多数考生学了程序设计以后,能基本了解教材的内容,能解答大部分前述三种类型的试题,平时还能指出别人程序的错误,但由于很少自己动手,或不知道从何着手编写程序等原因,自己还一直不会编程序。简单程序的设计通常要包含两个步骤:首先是设想计算方法,即用什么方法来解决给定的计算问题;其次是将求解方法告诉计算机,命令计算机怎么做。第一步工作人们采用常人的思维习惯,而第二步工作必须采用计算机的思维习惯。对于程序设计的初学者来说,最困难的可能还是很难适应计算机程序的思维习惯,人们几乎无法承受程序必须将要计算机完成的计算过程描述得几乎绝对的精细和精确。但对计算机来说,这又是非常必要的。编写程序就是在向计算机讲话,非常精确地告诉计算机怎么做。
「例8」编一个程序,从名为“text.txt”的文本文件中读取一个字符显示在屏幕上。
本例题要求实现最简单的文件处理。如考生知道文件处理程序的编写要点,就能方便地写出程序。
文件处理程序有以下几个要点:
(l)在程序的开始处,用包含预处理命令,包含标准文件stdio.h.定义文件指针变量和存储文件名的字符数组。如以下代码所示:
# include<stdio.h>
file *fp /* 定义文件指针变量 fp*/
char fname「40」=“某文件名”;
(2)如文件名在程序执行时输入,可用以下代码:
prinif(“请输入文件名(包括文件的目录路径、文件的扩展名)\n);
scanf(“%s%*c”,fname);/*输入文件名及其随后的回车符。/
(3)使用文件前,必须先打开文件,常用的有两种打开方式:
老文件打开为了让程序从正文文件输入数据,用读方式打开,则用以下代码:
if((fp=fopen(fname,“r‘’))== null) {/* 为读打开*/
printf(“%s文件不能打开,结束程序的执行\n”,fname);
return;
}
若文件打开为了让程序向正文文件输出数据,则用以下代码:
fp=fopen(fname,“w”);/*为写打开*/
读打开时,要求被打开文件已存在。写打开时,若被打开文件不存在,则建立一个以fname内容命名的新文件;若被打开文件已存在,则该文件上的数据被删除。
(4)文件使用结束后,要及时关闭,如以下代码所示:
fclose(fp);/* 以后中又可用于打开文件。/
(5)调用有关文件输入输出库函数。最经常使用的有:
调用函数 fgetc()从文件输入下一个字符,如:
ch= fgetc(fp);/*将输入字符存于变量 ch*/
调用函数fscanf()从文件按指定格式输入数据,如:
fscanf(fp,“%d%d”,&k,&j);/*从文件输入两个整数分别存于k和j*/除在第一位置增加一个文件指针变量实参外,其余与函数scanf()的用法全相同。
调用函数fputc()向文件输出一个字符,如:
fputc(ch,fp);/*将变量ch中的字符输出到文件。/
调用函数fprintf()向文件按指定格式输出数据,如:
fprintf(fp,“%d%d\n”,k,j);
该函数调用是按格式要求将k和j的值输出到文件。除在第一位置增加一个文件指针变量实参外,其余与函数prinif()的用法全相同。
(6)从正文文件逐一输入字符,作某种处理的程序结构为:
int c;/*若要用eof测试文件结束,则不能为char类型*/
file *fp;
……/*说明有关变量和设置初值等*/
if((fp=fopen文件名,“r”))==null){/*以输入方式打开*/
printf(“不能打开文件%s./n”,“文件名字符列”);
return;
}
while((c=fgetc(fp))!= eof){
……/* 这里对刚读人的字符信息c作某种处理*/
}
fclose(fp);
……/* 输出处理结果*/
(7)字符逐一生成输出,形成新文件程序的一般结构形式有:
int c;/*也可以是 char类型*/
对于本例题,只要包含上述(1)、(3)、(5)和(4)即可,写成完整程序如下:
# include<stdio.h>
file*fp;/*定义文件指针变量 fp*/
char fname[40]=“text.txt”;
main()
{char c;/*或 int c*/
if((fp= fopen(fname,“r”))== null){ /*为读打开*/
printf(“%s文件不能打开,结束程序的执行\n”,fname);
return;
}
c=fgetc(fp);/*将从文件输入的字符存于变量c*/
printf(“%c\n”, c);
fclose(fp);/*中所指文件关闭*/
}
「例9」编写函数f,该函数没有浮点型数组形参float[]和整型形参n,函数的功能是计算并返回p[]中前n个元素的平均值。由于函数返回已知数组的平均值,函数的头有以下形式:
float f( float p[], int n)
函数为了计算平均值,需要两个计算步骤,首先是求出数组元素之和,然后将求得的和除以元素个数。严格地说,函数还因防止形参n小于等于0的情况,假定当n小等于0时,函数返回0值。为求数组元素和,需要一个存储和的变量(例如说s)。求和通过遗历数组实现,有两种实现方法:
一是引入一个循环控制变量(例如说i),并让 i作为弓佣数组元素的下标(如 p[i])。所以有以下代码:
float f(float p[], int n)
{ int i; float s;
if(n<=0)return 0.0;
for( s=0.0, i=0; i<n; i++) s+= p[i];
return s/n;
}
二是由于函数的数组形参实际是一个指针变量,遍历数组直接可用指针形参p实现。循环次数可让变量 j控制, j的初值为 n,每次循环后让 j减 1,循环直至 j为 0结束。写成 c代码如下:
float f( float p[], int n)
{ floa s; int j=n;
if( n<=0) return 0.0;
for( s=0.0; j>0; j——) s+=*p++;
return s/n;
}
评论列表(0条)