资源描述
华中科技大学
C语言试验和课程设计
试验汇报
计算机科学和技术学院
指导老师:
目录
1 表示式和标准输入输出试验 ········ 3
2 步骤控制试验 ·············· 11
3 函数程序和结构试验 ··········· 20
4 编译预处理试验 ············· 28
5 数组试验 ················ 35
6 指针试验 ················ 42
7 结构和联合试验 ············· 52
8 文件试验 ················ 61
1 表示式和标准输入和输出试验
1.1 试验目标
(1) 熟练掌握多种运算符运算功效,操作数类型,运算结果类型及运算过程中类型转换,关键是C语言特有运算符,比如位运算符,问号运算符,逗号运算符等;熟记运算符优先级和结合性。
(2)掌握scanf 和printf 函数使用方法。
(3)掌握简单C程序(次序结构程序)编写方法。
1.2 试验内容及结果
1.2.1. 源程序改错
下面给出了一个简单C语言程序例程,用来完成以下工作:
(1)输入华氏温度f,将它转换成摄氏温度C后输出;
(2)输入圆半径值r,计算并输出圆面积s;
(3)输入短整数k、p,将k高字节作为结果低字节,p高字节作为结果高字节,拼成一个新整数,然后输出;
在这个例子程序中存在若干语法和逻辑错误。要求参考2.1.3和2.1.4步骤对下面程序进行调试修改,使之能够正确完成指定任务。
程序代码:
#include<stdio.h>
#define PI 3.14159;
voidmain( void )
{
int f ;
short p, k ;
double c , r , s ;
/* for task 1 */
printf(“Input Fahrenheit:” ) ;
scanf(“%d”, f ) ;
c = 5/9*(f-32) ;
printf( “ \n %d (F) = %.2f (C)\n\n ”, f, c ) ;
/* for task 2 */
printf("input the radius r:");
scanf("%f", &r);
s = PI * r * r;
printf("\nThe acreage is %.2f\n\n",&s);
/* for task 3 */
printf("input hex int k, p :");
scanf("%x %x", &k, &p );
newint = (p&0xff00)|(k&0xff00)<<8;
printf("new int = %x\n\n",newint);
}
【分析及更正】本程序共存在9处错误,分析以下:
(1)#define PI 3.14159;
错误原因:宏定义在预处理时会将后续程序中标示符展开为对应全部字符串,而PI不需要分号。
更正:去掉其后分号
(2)voidmain(void) {
错误原因:函数返回值和函数名之间应加空格,C90标准提议main函数应返回一个int作为状态值
更正:int main(void) {
(3)short p,k;
错误原因:后续用到了newint变量但并未申明
更正:short p,k,newint;
(4)scanf(“%d”, f );
错误原因:应该把要读入变量地址传输给scanf才能正确写入
更正:scanf("%d",&f);
(5)c = 5/9*(f-32) ;
错误原因:5和9是整型常数,相除会截断小数部分,应该将其中任意一个输表示为或转换为浮点数类型
更正:c = 5.0/9*(f-32);
(6)scanf("%f", &r);
错误原因:double类型对应占位符是%lf
更正:scanf("%lf",&r);
(7)printf("\nThe acreage is %.2f\n\n",&s);
错误原因:要输出s值应该将s作为参数传输给printf,不应传输其地址
更正:printf("\nThe acreage is %.2f\n\n",s);
(8)scanf("%x %x", &k, &p );
printf("new int = %x\n\n",newint);
错误原因:k,p为short类型,对应十六进制占位符应为%hx
更正:scanf("%hx %hx",&k,&p);
printf("new int = %hx\n\n",newint);
(9)newint = (p&0xff00)|(k&0xff00)<<8;
错误原因:要求将k高字节作为结果低字节,应该将k高字节提取出后右移至低字节
更正:newint=(p&0xff00)|(((k&0xff00)>>8)&0x00ff);
1.2.2 源程序修改替换
下面程序利用常见中间变量法实现两数交换,请改用不使用第3个变量方法实现。该程序中t是中间变量,要求将定义语句中t删除,修改下划线处语句,使之实现两数对调操作。
程序代码:
#include<stdio.h>
void main( )
{
int a, b, t;
printf(“Input two integers:”);
scanf(“%d %d”,&a,&b);
t=a ;a=b;b=t;
prinf(“\na=%d,b=%d”,a,b);
}
【分析】将a,b中任何一个看做原码,另一个当做密钥进行加密,再将加密过内容和密钥做加密运算即得到原码。由此使用异或运算进行交换。
步骤图以下:
【程序】
#include <stdio.h>
#include <stdlib.h>
int main(){
int a,b;
printf("input two integers:");
scanf("%d %d",&a,&b);
a ^= b;
b ^= a;
a ^= b;
printf("\na=%d, b=%d",a,b);
return 0;
}
【测试】假如输入a= 1,b=7,应该输出:a=7,b=1,程序运行结果以下,程序正确。
1.2.3 程序设计
1、编写一个程序,输入字符c,假如c是大写字母,则将c转换成对应小写,不然c值不变,最终输出c。
【分析】因为同一个字母大小写字母ASCII码值相差32,若ch为大写字母,则ch+32为对应小写字母。
步骤图以下:
【程序】
#include <stdio.h>
int main()
{
printf("Input your char x:\n");
char x;
scanf("%c",&x);
if(x>='a'&&x<='z')
{
printf("%c\n",x);
}
else if(x>='A'&&x<='Z')
{
printf("%c\n",x-'0'+32+'0');
}
else{
printf("Please input the right char.");
}
return 0;
}
【测试】
(1)测试大写变小写。若输入D,应输出d,程序运行结果以下,程序正确。
(2)测试其它字符。若输入a,应输出a,程序运行结果以下,程序正确。
2、编写一个程序,输入无符号短整数x,m,n(0≤m≤15, 1≤n≤16-m),取出x从第m位开始向左n位(m从右至左编号为0~15),并使其向左端(第15位)靠齐。
【分析】将x首先右移m位,再左移(16-n)位,则末尾会补0,即可将第m位开始向左n位且向最高位靠齐
步骤图以下:
【程序】
#include <stdio.h>
int main(){
unsigned short x,m,n;
puts("Please input x,m,n:");
scanf("%hu%hu%hu",&x,&m,&n);
x>>=m;
x<<=(16 - n);
printf("%hx\n",x);
return 0;
}
【测试】若 x=58207,m=4,n=4,因为(58207)10 = (1110 0011 0101 1111)2,处理后为(101 0000 0000 0000)2= (5000)16 ,程序应该输出十六进制数:5000,运行结果以下,程序正确。
3、IP地址通常是4个用句点分隔小整数(即点分十进制),如32.55.1.102。这些地址在机器中用无符号长整形表示。编写一个程序,以机器存放形式读入一个互联网IP地址,对其译码,然后用常见句点分隔4部分形式输出。比如,整形二进制表示就是:00101000 01011000 01011100 11010011,根据8位一组可表示为:40 88 92 211,因为CPU处理数据差异,它次序是颠倒,全部最终格式为211.92.88.40。
【分析】分别利用逻辑尺取出读入长整形数四部分,从最低位起每8位(1个字节)为一个部分,然后根据正常次序输出其对应十进制IP地址。
程序框图以下:
【程序】
#include <stdio.h>
int main(){
unsigned long IP;
unsigned short first, second, third, fourth;
puts("Input the IP in unsigned long int form:");
scanf("%lu",&IP);
first = (IP&0xFF000000)>>24;
second = (IP&0xFF0000)>>16;
third = (IP&0xFF00)>>8;
fourth =IP&0xFF;
printf("%hu.%hu.%hu.%hu",fourth,third,second,first);
}
【测试】若输入,应输出 211.92.88.40。运行结果以下,表明程序正确。
1.3 试验体会
在做改错题时,先浏览一遍,找出显著错误,然后将初步修改后代码输入编译器并编译,再依据编译器警告和错误提醒修改程序至完全正确,这个过程很需要细心和耐心,这个过程能够很好帮助我再以后不犯类似错误。
源程序修改和替换题锻炼我们举一反三能力,我们在平时写程序时就应该思索对于一个问题有没有多钟处理方案,不使用中间变量交换两个整数是很常见问题,我利用一个数异或本身等于0,0异或任意位保留原位原理来交换。
程序设计题提升了我们对所学知识熟练度和了解程度,只有实践才能学会C语言,在亲手编写代码过程中发觉问题,了解概念。
2步骤控制试验
2.1试验目标
(1)掌握复合语句、if语句、switch语句使用,熟练掌握for、while、do-while三种基础循环控制语句使用,掌握反复循环技术,了解转移语句和标号语句。
(2)熟练利用for、while、do-while语句来编写程序。
(3)练习转移语句和标号语句使用。
(4)使用集成开发环境中调试功效:单步实施、设置断点、观察变量值。
2.2试验内容及要求
2.2.1. 源程序改错
下面是计算s=n!源程序,在这个源程序中存在若干语法和逻辑错误。要求在计算机上对这个例子源程序进行调试修改,使之能够正确完成指定任务,比如,8!=40320。
程序代码:
#include<stdio.h>
int main()
{
int i,n,s=1;
printf("Please enter n:");
scanf("%d",n);
for(i=1;i<=n;i++)
s=s*i;
printf("%d!=%d",n,s);
return 0;
}
【分析及更正】本程序共存在3处错误,分析以下:
(1)int s=1;
错误原因:在计算阶乘时候,因为阶乘值会上升很快,所以不提议使用int类型,能够改为long或double型。
更正:改为long型变量。
(2)scanf(“%d”,n);
错误原因:scanf函数获取输入值时,引用是一个变量地址,而不是变量本身。
更正:scanf(“%d”,&n);
(3)} return 0;
错误原因:return返回值应该在main函数内部
更正:return 0;}
2.2.2 源程序修改替换
(1)修改上述计算s=n!源程序,要求分别用while和do-while语句替换for语句。
(2)修改上述计算s=n!源程序,要求输入改为“整数S”,输出改为“满足n! >=s最小整数n”。比如,输入整数40310,输出结果为n=8.
【分析】(1)相同循环内容利用不一样循环结构实现,需要注意不一样语句格式及依据循环方法对循环体做些许变动。步骤图以下:
while型 do-while型
(2)一样计算n!并将n!赋值给不是s值(比如说m),然后令m和s比较大小,找到符合条件第一个m值,并返回n值。步骤图以下:
【程序】(1)while型
#include <stdio.h>
int main()
{
int i=1,n,s=1;
printf("Please enter n:");
scanf("%d",&n);
while(i<=n){
s=s*i;
i++;}
printf("%d!=%d",n,s);
return 0;
}
do-while型
#include <stdio.h>
int main()
{
int i=1,n,s=1;
printf("Please enter n:");
scanf("%d",&n);
do{
s=s*i;
i++;
}
while(i<=n);
printf("%d!=%d",n,s);
return 0;
}
(2)
#include <stdio.h>
int main()
{
int i,n=0,s,m=1;
printf("Please enter s:");
scanf("%d",&s);
for(i=1;;i++){
m=m*i;
n++;
if(m>=s){
printf("n=%d",n);
break;
}
}
return 0;
}
【测试】(1)假如输入8,应该输出:40320,程序运行结果以下,程序正确。
(2)假如输入40310,应该输出:8,程序运行结果以下,程序正确。
2.2.3 程序设计
编写并上机调试运行能实现下列功效程序:
(1)假设工资税金按以下方法计算:x<1000元,不收取税金;1000<=x<,收取5% 税金;<=x<3000,收取10%税金;3000<=x<4000,收取15%税金;4000<=x<5000,收取20%税金;x>5000,收取25%税金。编写一个程序,输入工资金额,输出应收取税金额度,要求分别用if语句呵switch语句来实现。
(2)编写一个程序,将输入一行字符复制到输出,复制过程中将一个以上空格字符用一个空格替换。
(3)编写一个程序,打印以下杨辉三角形。
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
(4)编写一个程序,将用户输入任意正整数逆转。比如,输入1234,输出4321。
【分析】
(1)数学中分段函数问题,能够用if-else-if结构进行控制。在应用switch语句时候,结合分段区间特点设置适宜间断点。步骤图分别以下:
if型
switch型
(2)使用状态机经过判定空格个数选择不一样状态,从而实现消去空格作用。步骤图以下:
(3)依据所给公式利用循环实现杨辉三角数计算,注意题目中尤其提到输出格式,将每个数字设置为四个字符位,并循环输出空格符,实现金字塔效果。
(4)数次除10取余,每次全部分别输出余数,然后除以10并赋给原数反复计算,步骤图以下:
【程序】
(1)if型
#include <stdio.h>
float tax(float x);
int main()
{
float x;
printf("Please input your salary:");
scanf("%f",&x);
printf("You should pay %f yuan.\n",tax(abs(x)));
return 0;
}
float tax(float x){
float n;
if(x<1000){n=0;}
else if(x<){n=0.05;}
else if(x<3000){n=0.1;}
else if(x<4000){n=0.15;}
else if(x<5000){n=0.2;}
else{n=0.25;}
return n*x;
}
switch型
#include <stdio.h>
float tax(float x);
int main()
{
float x;
printf("Please input your salary:");
scanf("%f",&x);
printf("You should pay %f yuan.\n",tax(abs(x)));
return 0;
}
float tax(float x){
float n;
switch((int)(x/1000)){
case 0:n=0;break;
case 1:n=0.05;break;
case 2:n=0.1;break;
case 3:n=0.15;break;
case 4:n=0.2;break;
default:n=0.25;
}
return n*x;
}
(2)
#include <stdio.h>
enum {COPY,START,SPACE};
int main()
{
char c;
int state=COPY;
printf("Please input a char:\n");
while((c=getchar())!='\n'){
switch(state){
case COPY:
if(c==' ')state=START;
else putchar(c);
break;
case START:
putchar(' ');
if(c==' ')state=SPACE;
else{state=COPY;putchar(c);}
break;
case SPACE:
if(c!=' '){
state=COPY;
putchar(c);
}
else state=SPACE;
break;
}
}
return 0;
}
(3)
#include <stdio.h>
#define n 10
int main(void)
{
int i,j,k,c,m;
for(i=0;i<n;i++)
{
for(m=0;m<=n-i;m++){
printf(" ");
}
for(j=0;j<=i;j++)
{
if(j==0)c=1;
else
c=c*(i+1-j)/j;
printf("%4d",c);
}
printf("\n");
}
return 0;
}
(4)
#include <stdio.h>
int main()
{
long n,m;
printf("Please input an integer n(n>0):");
scanf("%ld",&n);
printf("\nThe new integer is:");
while(n>=10){
m=n%10;
printf("%ld",m);
n/=10;
}
printf("%ld",n);
return 0;
}
【测试】
(1)
(2)
(3)
(4)
2.3 试验体会
源程序改错中,依靠于平时良好输入习惯,在输入过程中已经能够检验出大多数语法错误,或拼写错误。接下来再检验一下逻辑是否有误,无误则进行多组数据编译检验,确定最终无误。
源程序修改和替换题锻炼我们举一反三触类旁通能力,在平时写程序时就应该思索对于一个问题有没有多钟处理方案,使用不一样逻辑结构多个尝试寻求最优解。
程序设计题则是自主设计实践,在练习中取得深入提升,增强对于所学知识熟练度和了解程度,锻炼能力。
3函数和程序结构试验
2.1试验目标
(1)熟悉和掌握函数定义、申明,函数调用和参数传输方法,和函数返回值类型 定义和返回值使用。
(2)熟悉和掌握不一样存放类型变量使用。
(3)熟悉多文件编译技术。
(4)使用集成开发环境中调试功效:单步实施、设置断点、观察变量值。
2.2试验内容及要求
2.2.1. 源程序改错
下面是计算s = 1!+2!+3!+…+n!源程序,在这个源程序中存在若干语法和逻辑错误。要求在计算机上对这个例子源程序进行调试修改,使之能够正确完成指定任务。
程序代码:
#include<stdio.h>
int main(void)
{
int k;
for(k=1;k<6;k++)
printf("k=%d\tthe sum is %ld\n", k, sum_fac(k));
}
return 0;
longsum_fac(int n)
{
long s = 0;
int i;
long fac;
for(i=1; i<=n; i++) fac *= i;
s += fac;
return s;
}
【分析及更正】本程序共存在3处错误,分析以下:
(1)} return 0;
错误原因:return返回值应该在main函数内部
更正:return 0;}
(2)long fac;
错误原因:fac未给予初始值,会造成接下来计算错误。
更正:long fac=1;
(3)s += fac;
错误原因:语句s += fac;不在函数for内部,逻辑犯错。
更正:for(i=1;i<=n;i++){
fac*=i;
s+=fac; }
2.2.2 源程序修改替换
(1)修改上术源程序中sum_fac函数,使其计算量最小。
(2)修改上述源程序中sum_fac函数,计算s =1+1/(2!)+1/(3!)+……+1/(n!)
【分析】(1)利用static变量类型对循环进行化简,保留上一个值,避免数次反复循环。步骤图以下:
(2)相比较于源程序,变动之处于于求是阶乘倒数和,则在循环中多一步求倒数过程,并对倒数求和。步骤图以下:
【程序】(1)
#include <stdio.h>
long sum_fac();
int main()
{
int k;
for(k=1;k<6;k++)
printf("k=%d\tthe sum is %ld\n",k,sum_fac(k));
return 0;
}
static long s=0,fac=1;
long sum_fac(int n)
{
fac*=n;
s+=fac;
return s;
}
(2)
#include <stdio.h>
float sum_fac();
int main()
{
int k;
for(k=1;k<6;k++)
printf("k=%d\tthe sum is %f\n",k,sum_fac(k));
return 0;
}
float sum_fac(int n)
{
long fac=1;
int i;
float x,s=0;
for(i=1;i<=n;i++){
fac*=i;
x=1.0/fac;
s+=x;
}
return s;
}
【测试】(1)程序运行结果以下,程序正确。
(2)程序运行结果以下,程序正确。
2.2.3跟踪调试
下面是计算fabonacci数列前n项和源程序,现要求单步实施该程序,并观察p,i,sum,n值,即:
(1)刚实施完“scanf(”%d”,&k);”语句时,p,i值是多少?
(2)从fabonacci函数返回后,光条停留在哪个语句上?
(3)进入fabonacci函数时,watches窗口显示是什么?
等图像。
(4)当i=3时,从调用fabonacci函数到返回,n值怎样改变?
n=1到n不存在;n=1到n=2到n不存在;n=1到n=2到n=3到n不存在。
【源程序】
#include <stdio.h>
long fabonacci(int);
int main()
{
int i,k;
long sum=0,*p=∑
scanf("%d",&k);
for(i=1;i<=k;i++){
sum+=fabonacci(i);
printf("i=%d\tthe sum is %ld\n",i,*p);
}
return 0;
}
long fabonacci(int n){
if(n==1||n==2)return 1;
else return fabonacci(n-1)+fabonacci(n-2);
}
2.2.4 程序设计
编写并上机调试运行能实现以下功效程序:
(1)编写一个程序,让用户输入两个整数,计算两个数最大条约数而且输出之。要求用递归函数实现求最大条约数,同时以单步方法实施该程序,观察其递归过程。
(2)编写一个程序,验证哥德巴赫猜想:一个大于等于4 偶数全部是两个素数之和。
(3) 编写一个程序,证实对于在符号常量BEGIN和END之间偶数这一猜测成立。如, 假如BEGIN为10,END为20,则程序输出应为:
GOLDBACH’SCONJECTURE:
Every even number n>=4 is the sum of two primes.
10=3+7
12=5+7
……
20=3+17
【分析】
(1)用辗转相除法求最大条约数,程序框图以下:
(2)首先判定一定范围内素数(比如100以内),然后判定一个偶数能否表示为两个素数之和。程序框图以下:
(3)和第二题类似,只不过加上一个范围控制,设置循环处于最大值和最小值之间。程序框图以下:
【程序】
(1)
#include <stdio.h>
int GCD(int m,int n);
int main()
{
int m,n,r;
printf("Please input two integers:\n");
scanf("%d%d",&m,&n);
printf("The greatest common divisor is %d",GCD(m,n));
return 0;
}
int GCD(m,n){
if(m%n==0&&m>=n)return n;
else if(m%n==0&&m<n)return m;
else{
int r;
r=m%n;
m=n;
n=r;
return GCD(m,n);
}
}
(2)
#include <stdio.h>
#define N 100
static int a[N];
int prime();
int main()
{
int x,i;
printf("Please input an even x(x>=4):\n");
scanf("%d",&x);
if(x%2!=0||x<4)printf("ERROR!");
prime();
for(i=2;i<=N&&i<x/2;i++){
if(a[i])
if(a[x-i]){printf("%d=%d+%d\n",x,i,x-i);}
}
return 0;
}
int prime(){
int i,j;
for(a[0]=a[1]=0,i=2;i<N;i++)a[i]=1;
for(i=2;i<N/2;i++)
if(a[i]){
for(j=i*i;j<N;j+=i)a[j]=0;
}
return 0;
}
(3)
#include <stdio.h>
#define N 100
#define BEGIN 10
#define END 20
static int a[N];
int prime();
int main()
{
int x,i,j;
printf("GOLDBACH'S CONJECTURE:\nEvery even number n>=4 is the sum of two prime.\n");
prime();
for(i=BEGIN;i<=END;i++){
for(j=2;j<i/2;j++){
if(a[j])
if(a[i-j]){printf("%d=%d+%d\n",i,j,i-j);}
}
}
return 0;
}
int prime(){
int i,j;
for(a[0]=a[1]=0,i=2;i<N;i++)a[i]=1;
for(i=2;i<N/2;i++)
if(a[i]){
for(j=i*i;j<N;j+=i)a[j]=0;
}
return 0;
}
【测试】
(1)输入24和16求最大条约数,最大条约数为8,结果正确:
(2)验证哥德巴赫猜想, 输入98,返回素数和,结果正确:
(3)验证一定范围内哥德巴赫猜想,输入14,返回素数和,结果正确:
2.3 试验体会
源程序改错中,依靠于平时良好输入习惯,在输入过程中已经能够检验出大多数语法错误,或拼写错误。接下来再检验一下逻辑是否有误,无误则进行多组数据编译检验,确定最终无误。
源程序修改和替换题锻炼我们优化算法能力,在平时写程序时就应该思索对于一个问题有没有最优处理方案,使用不一样语句在空间和时间中寻求平衡点,尽可能控制好占用时间空间范围。
程序设计题则是自主设计实践,在练习中取得深入提升,增强对于所学知识熟练度和了解程度,锻炼编写代码能力和并经过问题深入引申锻炼思维灵活性。
4编译预处理试验
4.1试验目标
(1)掌握文件包含、宏定义、条件编译、assert宏使用
(2)练习带参数宏定义、条件编译使用。
(3)练习assert宏使用。
(4)使用集成开发环境中调试功效:单步实施,设置断点,观察变量值。
4.2试验内容及要求
4.2.1. 源程序改错
下面是用宏来计算平方差和交换两数源程序。在这个源程序中,存在若干语法和逻辑错误,要求在计算机上对这个源程序进行调试修改,使之能够正确完成计算平方差和交换两数任务。
程序代码:
#include<std
展开阅读全文