C语言实验课 1. 编写程序,实现如下图标 *
***
*
#include<stdio.h>
int main ()
{
}
printf(" *\n ***\n *\n"); return 0;
2. 编程求解如下公式的结果
(10-2)*5
#include<stdio.h>
int main()
{
int i;
i=(10-2)*5;
printf("%d\n",i);
return 0;
3. 编程实现比较5,7和10三个数值的大小,输出最大数值。
#include<stdio.h>
int main()
{
int a;
a=(5>7)?5:a=(7>10)?7:10;
printf("10\n");
return 0;
}
4. 求余数,使用符号常量定义被除数,求30除以7的余数。
#include<stdio.h>
#define a 30
int main()
{
int b;
b=a%7;
printf("%d\n",b);
return 0;
}
5. 编程实现键盘输入总月数,用%运算符和/运算符将输入
的月份换成年数和月数的形式。
版本一:
#include<stdio.h>
int main()
{
int n,y,m;
printf("总月数:n=");
scanf("%d",&n);
y=n/12;
m=n%12;
printf("%d年%d个月\n",y,m);
return 0;
}
版本二:
#include<stdio.h>
int main()
{
int x,y,z;
scanf("%d",&z);
x=z/12;
y=z%12;
printf("%d年%d月",x,y);
return 0;
}
6. 年数中分为平年和闰年,编写程序,判断输入年数是闰
年还是平年,闰年输出为1,平年输出为0.
#include<stdio.h>
int main()
{
int year;
scanf("%d",&year);
if((year%4==0&&year%100!=0)||(year%400==0)) printf("1\n");
else
printf("0\n");
return 0;
}
7. 有分段函数,键盘输入x的值,使用条件运算符判断函
数y的值,并输出x和y的值,编写程序实现函数。
#include<stdio.h>
int main()
{
float y,x;
scanf("%f",&x);
y=(x>10)?10:(y=(x<-10)?-10:x);
printf("%f %f\n",x,y);
}
8. 某个班有x名学生,考试中有y人不及格,编写程序求
考试及格率,并用百分号形式打印在屏幕上。 版本一:
#include<stdio.h>
int main()
{
int x,y;
float s;
scanf("%d%d",&x,&y); s=(x-y)*100.0/x; printf("%f%%\n",s); return 0;
}
版本二:
#include<stdio.h> int main()
{
float x,y,a,b; char c='\045';
scanf("%d,%d",&x,&y); a=x-y;
b=(x-y)/x*100; printf("%f",b); putchar(c);
return 0;
}
9. 编写程序,计算1到100之间的偶数和,使用for循环语句,用sum表示结果。
#include<stdio.h>
int main()
{
int i,sum=0;
for(i=2;i<=100;i=i+2)
sum=sum+i;
printf("1~100的偶数和为%d\n",sum);
}
return 0;
10. 编写程序,计算100到1000之间能被7和11整除的数,并打印到屏幕上,每3个数为一行。
#include<stdio.h>
int main()
{
int i,j=0;
for(i=100;i<=1000;i++)
{
}
return 0;
}
if(i%7==0&&i%11==0) {printf("%d ",i); j++; if(j%3==0) printf("\n");}
11. 编写程序,计算Sum=x+xx+xxx+xxxx+x…x的值。其
中x为1到9之间的数字,例如:3+33+333+3333+33333.键盘输入x的值和数项的值,比如上述算式中x的值应该为3,共5项和数,则应该输入参数3和5.
#include<stdio.h>
int main()
{
int a,n,i=1,sum=0,t=0;
scanf("%d%d",&a,&n);
while(i<=n)
{
}
printf("a+aa+aaa+...=%d\n",sum);
return 0;
}
t=t+a; sum=sum+t; a=a*10; ++i;
12. 从键盘输入字符,记录并打印键盘输入的字符数,同
步输出键入的字符,直到键盘输出!停止。调用getchar函数用于接收键盘输入的字符数,使用while循环,只要输入字符非!号符,则继续等待键盘键入。
#include <stdio.h>
int main()
{
char a;
int b=0;
while((a=getchar()) != '!')
{b++;
printf("%c",a);
}
printf("\n");
printf("%d\n",b);
return 0;
}
13. 编写程序,计算1到1000之间直接能够被7整除的
所有正整数,并打印在屏幕上,使用continue语句控制程序执行,每行打印10个数字。
#include <stdio.h>
int main()
{
int i,j=0; for(i=1;i<=1000;i++) {if(i%7!=0) continue; printf("%d ",i);
}
j++; if(j%10==0) printf("\n");} printf("\n"); return 0;
14. 给一个不多于5位的正整数,要求:
1. 求出它是几位数
2. 分别输出每一位数字
3. 按逆序输出每一位数字
版本一:
#include <stdio.h>
void main()
{
long int r;
int a,b,c,d,e;
scanf("%d",&r);
a=r/10000;
b=(r-a*10000)/1000;
c=(r-a*10000-b*1000)/100;
d=(r-a*10000-b*1000-c*100)/10; e=r-a*10000-b*1000-c*100-d*10; if (a!=0) printf("5位数\n");
else if (b!=0) printf("4位数\n"); else if (c!=0) printf("3位数\n"); else if (d!=0) printf("2位数\n"); else if (e!=0) printf("1位数\n");
printf("%d%d%d%d%d\n",a,b,c,d,e); printf("%d%d%d%d%d\n",e,d,c,b,a); }
版本二:
#include<stdio.h>
int main()
{
int a,b,c,d,e,l,k,j,h,g,m; scanf("%d",&a);
b=a/10000;
c=a/1000;
d=a/100;
e=a/10;
if(b>=1)
printf("b是五位数");
else
if(c>=1)
printf("b是四位数");
else
if(d>=1)
printf("b是三位数");
else
if(e>=1)
printf("b是两位数")
else
printf("b是一位数");
l=b;
k=c-10*b;
j=d-10*c;
h=e-10*d;
g=a-10*e;
m=g*10000+h*1000+j*100+k*10+l;
printf("%d,\n%d,\n%d,\n%d,\n%d,\n",l,k,j,h,g); printf("%d",m);
return 0; }
第二篇:二级C语言上机 总结
二级C语言上机指导
一、填空题考点分析:
(一)、文件函数的各个参数的意义
常考的有fopen(),fseek(),fprintf(),fscanf(),fclose(),fwrite(),fread(),feof(),rewind(fp)在这里要明确每一个函数的参数的意义及使用方法。文件结构体:(FILE)
缓冲文件系统为每个正在适用的文件都在内存开辟的文件信息区该文件信息用系统定义的名为FILE的结构体描述
注意:文件结构体(FILE)包含在stdio.h头文件中
typedefstruct
{
int_fd;
int_cleft;
int_mode;
char*_next;
char*_buff;
}FILE;
例:FIEL*fp;//文件号//缓冲区中剩下的字符数//文件操作方式//文件当前读写位置//文件缓冲区位置
如fopen()的使用方法是:fopen函数用来打开一个文件,其调用的一般形式为:文件指针名=fopen(文件名,使用文件方式);
其中,
“文件指针名”必须是被说明为FILE类型的指针变量;
“文件名”是被打开文件的文件名;
“使用文件方式”是指文件的类型和操作要求。“文件名”是字符串常量或字符串数组。
文件使用方式
“rt”
“wt”
“at”意义只读打开一个文本文件,只允许读数据只写打开或建立一个文本文件,只允许写数据追加打开一个文本文件,并在文件末尾写数据
“rb”
“wb”
“ab”
“rt+”
“wt+”
“at+”
“rb+”
“wb+”
“ab+”只读打开一个二进制文件,只允许读数据只写打开或建立一个二进制文件,只允许写数据追加打开一个二进制文件,并在文件末尾写数据读写打开一个文本文件,允许读和写读写打开或建立一个文本文件,允许读写读写打开一个文本文件,允许读,或在文件末追加数据读写打开一个二进制文件,允许读和写读写打开或建立一个二进制文件,允许读和写读写打开一个二进制文件,允许读,或在文件末追加数据
fclose(文件指针);fclose()的使用比较简单,
格式化输入输出的格式为:
fscanf(文件指针,格式字符串,输入表列);
fprintf(文件指针,格式字符串,输出表列);
而fseek()的说明是fseek函数用来移动文件内部位置指针,其调用形式为:
fseek(文件指针,位移量,起始点);
其中:
“文件指针”指向被移动的文件。
“位移量”表示移动的字节数,要求位移量是long型数据,以便在文件长度大于64KB时不会出错。当用常量表示位移量时,要求加后缀“L”。
“起始点”表示从何处开始计算位移量,规定的起始点有三种:文件首,当前位置和文件尾。其表示方法如下表。
起始点
文件首
当前位置
文件末尾表示符号SEEK_SETSEEK_CURSEEK_END数字表示012
fread(buffer,size,count,fp);
写数据块函数调用的一般形式为:
fwrite(buffer,size,count,fp);
其中:
buffer是一个指针,在fread函数中,它表示存放输入数据的首地址。在fwrite函数中,它表示存放输出数据的首地址。
size表示数据块的字节数。
count表示要读写的数据块块数。
fp表示文件指针。
判断文件是否结束函数一般形式:
feof(fp)
文件结束返回真值(非0);文件未结束返回假值(0)
重置文件位置指针到文件开头函数一般形式:
rewind(fp)
在以上的这些函数中一般所填的空是文件指针(fp)。
如(第二、三、四、五、15、22套等)题中:
第三套:
#include<stdio.h>
#defineN5
typedefstructstudent{
longsno;
charname[10];
floatscore[3];
}STU;
voidfun(char*filename,STUn)
{FILE*fp;
/**********found**********/
fp=fopen(__1__,"rb+");
/**********found**********/
fseek(__2__,-1L*sizeof(STU),SEEK_END);
/**********found**********/
fwrite(&n,sizeof(STU),1,__3__);
fclose(fp);
}
main()
{STUt[N]={{10001,"MaChao",91,92,77},{10002,"CaoKai",75,60,88},
{10003,"LiSi",85,70,78},{10004,"FangFang",90,82,87},
{10005,"ZhangSan",95,80,88}};
STUn={10006,"ZhaoSi",55,70,68},ss[N];
inti,j;FILE*fp;
fp=fopen("student.dat","wb");
fwrite(t,sizeof(STU),N,fp);
fclose(fp);
fp=fopen("student.dat","rb");
fread(ss,sizeof(STU),N,fp);
fclose(fp);
printf("\nTheoriginaldata:\n\n");
for(j=0;j<N;j++)
{printf("\nNo:%ldName:%-8sScores:",ss[j].sno,ss[j].name);
for(i=0;i<3;i++)printf("%6.2f",ss[j].score[i]);
printf("\n");
}
fun("student.dat",n);
printf("\nThedataaftermodifing:\n\n");
fp=fopen("student.dat","rb");
fread(ss,sizeof(STU),N,fp);
fclose(fp);
for(j=0;j<N;j++)
{printf("\nNo:%ldName:%-8sScores:",ss[j].sno,ss[j].name);
for(i=0;i<3;i++)printf("%6.2f",ss[j].score[i]);
printf("\n");
}
}
本题中的第一个空就是与fopen相关的,看到在本题中已经给出了打开文件的方式则前一个位置填的一定是文件名,而在本题中文件名是通过形参传递过来的,所以只能填写filename了。
第一处:从指定的文件中读出数据,所以应填:filename。
第二处:读取文件fp的最后一条记录,所以应填:fp。
第三处:再把读出的记录,写入文件fp指定的位置上,所以应填:fp。
(二)、数据定义:
这类题集中在定义变量的类型,函数类型,形参的类型及形参名1、变量的类型中爱出的考题一般在指向文件的指针的定义方法:FILE*如在第二套的填空中就是这种考法,要注意FILE必须大写,而且要注意指针,如果他给的没有*则在定义时用户必须加上*。
如(第2、14套等)题:
#include<stdio.h>
voidfun(char*s,inta,doublef)
{
/**********found**********/
__1__fp;
charch;
fp=fopen("file1.txt","w");
fprintf(fp,"%s%d%f\n",s,a,f);
fclose(fp);
fp=fopen("file1.txt","r");
printf("\nTheresult:\n\n");
ch=fgetc(fp);
/**********found**********/
while(!feof(__2__)){
/**********found**********/
putchar(__3__);ch=fgetc(fp);}
putchar('\n');
fclose(fp);
}
main()
{chara[10]="Hello!";intb=12345;
doublec=98.76;
fun(a,b,c);
}
解析:
本题是考察先把给定的数据写入到文本文件中,再从该文件读出并显示在屏幕上。第一处:定义文本文件类型变量,所以应填:FILE*。
第二处:判断文件是否结束,所以应填:fp。
第三处:显示读出的字符,所以应填:ch。
2、形参类型及形参名
①形参类型
在这种类型题中判断起来还是比较容易的,并且在现在考题中也有增多的趋势,一般判断方法是形参的类型应该与实参的类型相一致,也就是说调用用的参数类型就是形参的类型。
如(第八套、35)题
#include<stdio.h>
typedefstruct
{intnum;
charname[9];
floatscore[3];
}STU;
voidshow(STUtt)
{inti;
printf("%d%s:",tt.num,tt.name);
for(i=0;i<3;i++)
printf("%5.1f",tt.score[i]);
printf("\n");
}
/**********found**********/
voidmodify(___1___*ss,floata)
{inti;
for(i=0;i<3;i++)
/**********found**********/
ss->___2___*=a;
}
main()
{STUstd={1,"Zhanghua",76.5,78.0,82.0};
floata;
printf("\nTheoriginalnumberandnameandscores:\n");
show(std);
printf("\nInputanumber:");scanf("%f",&a);
/**********found**********/
modify(___3___,a);
printf("\nAresultofmodifying:\n");
show(std);
}
解析:
本题是利用结构体存储学生记录并由实参ss返回。
第一处:实参ss是一个结构型指针变量,所以应填:STU。
第二处:该学生的各科成绩都乘以一个系数a,所以应填:score[i]。第三处:函数的调用,由于函数定义时使用的指针结构型变量,所以应填:&std。
②填形参名的题目
这类题也是比较简单的,在子函数中从上往下看,如果看到变量没有声明,并且该变量不是全局变量则该变量名就应该是形参。
如(第七套)题:
#include<stdio.h>
typedefstruct
{intnum;
charname[9];
charsex;
struct{intyear,month,day;}birthday;
floatscore[3];
}STU;
/**********found**********/
voidshow(STU___1___)
{inti;
printf("\n%d%s%c%d-%d-%d",tt.num,tt.name,tt.sex,
tt.birthday.year,tt.birthday.month,tt.birthday.day);
for(i=0;i<3;i++)
/**********found**********/
printf("%5.1f",___2___);
printf("\n");
}
main()
{STUstd={1,"Zhanghua",'M',1961,10,8,76.5,78.0,82.0};
printf("\nAstudentdata:\n");
/**********found**********/
show(___3___);
}
在本题中第一个空就应该填形参名,而从上往下看时,发现tt是前面没有声明的变量,并且类型与想要定义的类型是一致的,所双该空应该填的是tt
第一处:tt变量在函数体fun已经使用,所以应填:tt。
第二处:利用循环分别输出学生的成绩数据,所以应填:tt.score[i]。
第三处:函数的调用,所以应填:std。
3、函数返回值的类型
这种类型的判断方法也是根据函数的定义方法来看:在C语言中定义函数的格式是函数
函数类型函数名(形参类型1形参名1,形参类型2形参名……)
如果在函数名前有空则一定是填函数类型,而函数类型一定要和返回值的类型是一致的,也可以在主函数中看将函数的值赋给了什么样的变量,一般他们的类型也应该是一致的。
如(第六套、19、24、25套等)题
#include<stdio.h>
doublef1(doublex)
{returnx*x;}
doublef2(doublex,doubley)
{returnx*y;}
/**********found**********/
__1__fun(inti,doublex,doubley)
{if(i==1)
/**********found**********/
return__2__(x);
else
/**********found**********/
return__3__(x,y);
}
main()
{doublex1=5,x2=3,r;
r=fun(1,x1,x2);
r+=fun(2,x1,x2);
printf("\nx1=%f,x2=%f,x1*x1+x1*x2=%f\n\n",x1,x2,r);
}
解析:
本题是根据给定的公式来计算函数的值。
第一处:程序中使用双精度double类型进行计算,所以函数的返回值类型也为double,所以应填:double。
第二处:当i等于1时,则返回f1函数的值,所以应填:f1。
第三处:如果i不等于1,则返回f2函数的值,所以应填:f2。
在本题中发现第一个空出现在子函数名之前,则这一定是要填函数类型,而子函数中看到返回值是double类型,所以该函数的类型一定是double型的,所以该空应该填double一看在本题中的第一个空就是要填函数的类型,而再看返回值是a那么a的类型是structstudent,所以该函数的类型是structstudent.
(三)、给变量赋初始值。
这类问题要注意的有类型的问题,链表中指针的初值,循环变量的初值等等。
①和,积,计数变量赋初值的问题
如(第27套)题
#include<stdio.h>
doublefun(intn)
{inti;doubles,t;
/**********found**********/
s=__1__;
/**********found**********/
for(i=1;i<=__2__;i++)
{t=2.0*i;
/**********found**********/
s=s+(2.0*i-1)*(2.0*i+1)/__3__;
}
returns;
}
main()
{intn=-1;
while(n<0)
{printf("Pleaseinput(n>0):");scanf("%d",&n);
printf("\nTheresultis:%f\n",fun(n));
}}
在本题中做为S就是要初使值根据题目,s是存放和的,和的初值一般是0,类似的还有像存放积的应该置1,存放个数的初值应该是0。
第一处:根据公式可知,累加和变量s,应置0。
第二处:for循环的终止值应为形参n。
第三处:根据公式以及函数体中t变量内容,所以应填:t*t。
②链表中初值的问题。
注意动态存储分配函数:在ANSIC中以下函数包含在”stdlib.h”头文件中,在TURBOC中包含在”alloc.h”头文件中
动态分配空间函数malloc
(类型*)malloc(size)
动态分配多块空间函数calloc
(类型*)calloc(n,size)或(类型*)calloc(size,n)(第五套)
释放空间函数free
free(fp)
如(第11、12、13、26、36套)题
#include<stdio.h>
#include<stdlib.h>
#defineN5
typedefstructnode{
intdata;
structnode*next;
}NODE;
voidfun(NODE*h)
{NODE*p,*q,*r;
/**********found**********/
p=h->__1__;
/**********found**********/
if(p==__2__)return;
q=p->next;
p->next=NULL;
while(q)
{r=q->next;q->next=p;
/**********found**********/
p=q;q=__3__;
}
h->next=p;
}
NODE*creatlist(inta[])
{NODE*h,*p,*q;inti;h=(NODE*)malloc(sizeof(NODE));h->next=NULL;
for(i=0;i<N;i++)
{q=(NODE*)malloc(sizeof(NODE));
q->data=a[i];
q->next=NULL;
if(h->next==NULL)h->next=p=q;else{p->next=q;p=q;}}
returnh;
}
voidoutlist(NODE*h)
{NODE*p;
p=h->next;
if(p==NULL)printf("ThelistisNULL!\n");else
{printf("\nHead");
do
{printf("->%d",p->data);p=p->next;}
while(p!=NULL);
printf("->End\n");
}
}
main()
{NODE*head;
inta[N]={2,4,6,8,10};
head=creatlist(a);
printf("\nTheoriginallist:\n");
outlist(head);
fun(head);
printf("\nThelistafterinverting:\n");
outlist(head);
}
在链表中为了方便查找,而增加了一个头指针,要知道头结点的data部分是没有内容的,用头结点的目的是为了用他的next部分来存放真正第一个结点的地址,而由于链表中知道一个结点能够找到他后面的所有结点但是不能找到前面的结点,所以在查找或定位时,如在插入,删除,交换时指针的初值都是从头指针开始,而在使用其data内容时指针的初值是从h->next开始的。
在本题中,是为了将链表逆置,在题目上已经给出了“p->”说明只能添next或data,由于是将值赋给了指针,所以本题只能填next.
而第二个空,应该是当链表结束时,该过程就应该停止了,而在链表中停止的标志当p==NULL时表示的,所以第二个空是NULL或0
第三个空是本题中最难的一个,他考的是结点移动的过程。但是从另一个方面也能够分析出来他应该填的内容。首先从while(q)说明这个循环是以q的值为结束标志,这就是说q的内容一定要变化,而一般的变化是将q向后移动到原q的后一个结点上,即q->next上,而在本题上先已经将q->next保存在r中,所以应该把r再赋给q,则该空应该填r.
(四)、定循环变量的终止值。
这类问题一定都是结合具体题目来分析的。如在字符串中是以0或’\0’做为结束标志的,而在链表中以是NULL为结束标志的,在数组中一般以个数做为结束标志的。
如(第100套)题
#include<stdio.h>
voidfun(char*s,charc)
{inti,j,n;
/**********found**********/
for(i=0;s[i]!=___1___;i++)
if(s[i]==c)
{
/**********found**********/
n=___2___;
while(s[i+1+n]!='\0')n++;
for(j=i+n+1;j>i;j--)s[j+1]=s[j];
/**********found**********/
s[j+1]=___3___;
i=i+1;
}
}
main()
{chars[80]="baacda",c;
printf("\nThestring:%s\n",s);
printf("\nInputacharacter:");scanf("%c",&c);
fun(s,c);
printf("\nTheresultis:%s\n",s);
}
本题中第一个空就是填结束标志的,而在本题中由于是字符串的结束标志所以可以填0或’\0’。第二个空乍一看起来不知道应该怎么填,但仔细看看,则能发现这个题目的要求是在字符串中插入字符c,所以插入的过程一定是从后向前把每个元素向后移动,而下面的语句正是向后移动的再看n的作用是定位置的,所以n的初值应该是0,最后一个空,能看出来是应该将c插入的,所以只能填c了.
(五)、算法本身的内容。(16)
这类空是最难的了,作为考生在平时要尽可能多的积累算法,要多看,多想,多练,这样才能更快的,更好的答好填空题。如下题:
#include<stdio.h>
#defineN9
/**********found**********/voidfun(int___1___,intn){inti,j,max,min,px,pn,t;/**********found**********/for(i=0;i<n-1;i+=___2___){max=min=a[i];
px=pn=i;
/**********found**********/
for(j=___3___;j<n;j++)
{if(max<a[j])
{max=a[j];px=j;}
if(min>a[j])
{min=a[j];pn=j;}
}
if(px!=i)
{t=a[i];a[i]=max;a[px]=t;if(pn==i)pn=px;
}
if(pn!=i+1)
{t=a[i+1];a[i+1]=min;a[pn]=t;}}
}
main()
{intb[N]={1,4,2,3,9,6,5,8,7},i;printf("\nTheoriginaldata:\n");
for(i=0;i<N;i++)printf("%4d",b[i]);printf("\n");
fun(b,N);
printf("\nThedataaftermoving:\n");for(i=0;i<N;i++)printf("%4d",b[i]);printf("\n");
}
在本题中,第一空是定义的形参的内容,不是很难,能够看到主函数中调用方式,所以这个位置应该填指针或数组名即*a或a[]都是对的。
而第二个空完全是建立在算法之上的,由于一次排序中既找了最大值,又找了最小值,也就是说一次排完了两个元素,所以每次i应该加2
第三个空:由于已经假设了i位置是最大或最小了,所以从算法的角度能知道j的起始位置应该从i+1处开始了。
二、改错的答题技巧
改错的答题步骤,打开程序以后一定要先编译,这样一部分语法错误码就可以直接找到了,如大小写的问题,if语句后面没有括号的问题,在编译过程中警告错误码也要仔细看好,也可能是出现错的地方,编译以后去运行一下,看结果是不是对了,如果不对那就是算法错误了,而在考试中错误就在FOUND的下一行,所以就集中精力攻这一行,也可以上下贯通找出错误所在。
改错题的常见考点分析:
(一)、语法错误
这类问题比较简单,在编译中就可以发现,所考察的知识点都是比较基本的,要求同学们对于基本的语法有个准确的掌握。如:在C语言中的关键词大多数都为小写,只有FILE,NULL是大写的,
if的语法格式为:
if(表达式)
语句
else
语句
while的语法格式为:
while(表达式)
语句.
这类基本语法必须要熟练掌握。
(二)、变量或函数定义错误
如下题
#include<stdio.h>
doublefun(intx[])
{
/************found************/
intsum=0.0;
intc=0,i=0;
while(x[i]!=0)
{if(x[i]>0){
sum+=x[i];c++;}
i++;
}
/************found************/
sum\=c;
returnsum;
}
main()
{intx[1000];inti=0;
printf("\nPleaseentersomedata(endwith0):");
do
{scanf("%d",&x[i]);}
while(x[i++]!=0);
printf("%f\n",fun(x));
}
在本题中函数的类型是double型的,而返回值是sum却它定义成了int,所以应该将int改成double,第二处错误,就是语法错误了,在编译时就能发现,他的除号是反了。如(第二套)题:
#include<stdio.h>
#include<stdlib.h>
typedefstructaa
{intdata;
structaa*next;
}NODE;
NODE*Creatlink(intn,intm)
{NODE*h=NULL,*p,*s;
inti;
/**********found***********/
p=(NODE)malloc(sizeof(NODE));
h=p;
p->next=NULL;
for(i=1;i<=n;i++)
{s=(NODE*)malloc(sizeof(NODE));
s->data=rand()%m;s->next=p->next;
p->next=s;p=p->next;
}
/**********found***********/
returnp;
}
outlink(NODE*h)
{NODE*p;
p=h->next;
printf("\n\nTHELIST:\n\nHEAD");
while(p)
{printf("->%d",p->data);
p=p->next;
}
printf("\n");
}
main()
{NODE*head;
head=Creatlink(8,22);
outlink(head);
}
本题中是链表题,这类题是很多同学不敢看的题,实际上,这种题并没有想象中的那么难,只要把最基本的内容掌握好,完全可以把题做出来,在改错题中错误只在FOUND的下一行,看第一处p=(NODE)malloc(sizeof(NODE));这句话的作用是在内存中申请一个新的结点,而malloc的返回值是首字节的地址,所以在强制转换时也只能转换成指针型,那么在本题中应该改为p=(NODE*)malloc(sizeof(NODE));再看第二处在returnp;发现return这个词没有拼写错误,再看到该函数的应该返回的内容是链表的头结点,而头结点的指针是h,所以应该返回h.
(三)、指针处的错误
在这种错误中,一般形参是指针,而在使用时却直接对参数赋值,造成错误。
(四)、运算中的数据类型的问题
在这类问题当中主要考虑的是整型与整型做除法是结果为整型的问题,所以要注意类型
转换。
#include<stdio.h>
doublefun(intm)
{
doublet=1.0;
inti;
for(i=2;i<=m;i++)
/**********found**********/
t=1.0-1/i;
/**********found**********/
_______;
}
main()
{
intm;
printf("\nPleaseenter1integernumbers:\n");
scanf("%d",&m);
printf("\n\nTheresultis%lf\n",fun(m));
}
在这个题中的第一处错误,就是这种问题,由于i是整型的,所以1/i的结果一定是整型的0,那么这个程序的结果一定是不正确的。所以前面应该是1.0/i,并且该题是求累计差,所以应该是t-=1.0/i;第二处实际上已经成为填空题了,在考试中这类题还是相当少的。
(五)、算法错误
这类错误是改错中最难的了,这类程序能够运行,但是结果不对,这就靠大家对于算法的理解与认识才能改出来。如:
#include<stdio.h>
#include<string.h>
#defineN80
voidfun(char*s,chart[])
{inti,j=0;
for(i=0;i<strlen(s);i++)
/***********found**********/
if(i%2&&s[i]%2==0)
t[j++]=s[i];
/***********found**********/
t[i]='\0';
}
main()
{chars[N],t[N];
printf("\nPleaseenterstrings:");gets(s);
fun(s,t);
printf("\nTheresultis:%s\n",t);
}
在本题中第一处错误就是在题目中要求是下标为奇数,或ASCII的偶数的保存,所以应该是if(i%2||s[i]%2==0)才对。
三、编程题的做法
编程题考查的内容都是每一种数据结构中的最基本的问题,所以对于这种问题一定要先把每种结构中的最基本问题弄清楚,象数组中的基本运算,字符串中的基本运算,链表中的基本运算以及老师在循环中讲解的常用算法,象在数中求每一位的算法,级数的算法,质数的算法,求和,求阶乘的算法,对于这些算法在平时的复习中一定要熟记,而在考试中的很多题都是在此类算法的基础上进行演化的。在编程中注意:
(一)、对于数学问题
能化简的尽量化简,这样就把编程的压力转化到数学上了。如
#include<stdio.h>
floatfun(intn)
{
}
main()
{intn;floats;
printf("\nPleaseenterN:");scanf("%d",&n);
s=fun(n);
printf("theresultis:%f\n",s);
NONO();
}
NONO()
{/*本函数用于打开文件,输入数据,调用函数,输出数据,关闭文件。FILE*fp,*wf;
inti,n;
floats;
fp=fopen("C:\\WEXAM\\24990001\\in.dat","r");
wf=fopen("C:\\WEXAM\\24990001\\out.dat","w");
for(i=0;i<10;i++){
fscanf(fp,"%d",&n);
s=fun(n);
fprintf(wf,"%f\n",s);
}
fclose(fp);
fclose(wf);
}*/
在该题中是要求前n的数的和的倒数和.由数学关系可知前n的数的和为n*(n+1)/2而倒数就是2/(n*(n+1))在数学上又知道上这个表达式相当于2*(1/n-1/(n+1))而这个和的最终结果就是2(1-1/(n+1))即2*n/(n+1),所以该程序就可以这样写:
floatfun(intn)
{
return2.0*n/(n+1);
}
(二)字符串的问题
这类问题不是很难,需要知道字符串中的处理过程,首先是字符串中以0或’\0’结束,然后所谓的ASCII就是字符串中的元素。再根据题要求思考对应的算法。
如(第三套)题:
#include<stdio.h>
#include<string.h>
#defineN80
intfun(char*s)
{
}
main()
{charline[N];intnum=0;
printf("Enterastring:\n");gets(line);
num=fun(line);
printf("Thenumberofwordis:%d\n\n",num);
NONO();
}
NONO()
{/*请在此函数内打开文件,输入测试数据,调用fun函数,输出数据,关闭文件。*/FILE*rf,*wf;inti,num;charline[N],*p;
rf=fopen("C:\\WEXAM\\24990001\\in.dat","r");
wf=fopen("C:\\WEXAM\\24990001\\out.dat","w");
for(i=0;i<10;i++){
fgets(line,N,rf);
p=strchr(line,'\n');
if(p!=NULL)*p=0;
num=fun(line);
fprintf(wf,"%d\n",num);
}
fclose(rf);fclose(wf);
}
分析:本题是求单词个数,并且单词之间是由一个或多个空格隔开,也就是说在一行中只计算空格的个数并不能得到单词的个数,那么可以统计该位置是空格而下一个位置不是空格的个数。
intfun(char*s)
{
intk=1,i=0;
while(s[i]){
if(s[i]==''&&s[i++]!=’‘)k++;
i++;
}
returnk;
}
(三)必杀——输入文件
注意:此方法并不适用于所有题,如求3~100之间所有质数平方根的和。
如(第3、5、套等)题