四川师范大学计算机科学学院
《C语言程序设计》
实
验
手
册
20xx年2月
年级: 2009级
专业: 电子商务
班级: 04班
姓名: 罗桂清
学号: 2009110438
指导教师: 廖雪花 1
《C语言程序设计》实验课程简介
课程名称:C语言程序设计实验
课程性质:专业必修课
课程属性:专业必修课
学时学分:学时32 学分1
开课实验室:软件实验室
面向专业:网络工程、软件工程、计算机科学与技术
一、课程的任务和基本要求
C语言程序设计实验是面向计算机相关专业学生开设的《C语言程序设计》实验课,是配合《C语言程序设计》课程而开设的实验性教育环节。本课程的主要任务是让学生充分掌握C语言程序设计的基本概念、各种数据类型的使用技巧、模块化程序设计的方法等。C语言程序设计实验对课程中所涉及的知识进行验证,同时也是学生很好地学习课程的辅助手段。通过C语言上机实验的教学活动,使学生真正全面掌握C语言的基础知识,培养和提高学生的程序开发能力。
二、实验项目
【实验一】最简单的C程序---顺序程序设计
【实验二】逻辑运算和判断选取控制
【实验三】循环结构程序设计(一)
【实验四】循环结构程序设计(二)
【实验五】函数
【实验六】数组(一)
【实验七】数组(二)
【实验八】指针
【实验九】结构体、共用体和文件
【实验十】C程序综合性实验
三、有关说明
1、与其它课程和教学环节的联系:
先修课程:计算机文化
后续课程:面向对象程序设计、Java程序设计、数据结构、软件工程
2、教材和主要参考书目:
(1)教材:
《C程序设计习题解答与上机指导》,谭浩强 吴伟民著,北京:清华大学出版社,20xx年。
(2)主要参考书目:
《C语言程序设计》 谭浩强主编,清华大学出版社,20xx年。
2
三、实验内容
实验一 最简单的C程序---顺序程序设计
(验证性实验 2学时)
(一)、实验目的
1.熟悉win-tc程序运行环境
2.掌握运行一个C程序的步骤,理解并学会C程序的编辑、编译、链接方法
3.掌握C语言中使用最多的一种语句——赋值语句
4.掌握数据的输入输出方法,能正确使用各种格式控制符
(二)、实验内容
1.写出下列程序的运行结果
(1)#include <stdio.h>
void main()
{
printf(“*****************\n”);
printf(“This is a c program. \n”);
printf(“****************\n”);
}
运行结果及分析:
运行结果:
*****************
This is a c program
*****************
分析:
1. c程序中的#include<stdio.h>是指一个标准输入输出文件,它包含了标准输入输出函数。
2. 一个c程序中必须只能有一个main函数,void main()是指子最后不给程序返回任何值;
3. 这个程序中的prinft函数是用来显示输出的,这三条命令全都会显示输出。 将程序中的\n去掉后,运行结果及分析:
运行结果:
************************This is a program*************************** 分析:
1. 一个c程序中必须只能有一个main函数,void main()是指子最后不给程序返回任何值;
2.c程序支持一些特殊的反斜杠字符常量,这些常量常用于输出函数中,\n是指换行输出,所以将\n去掉后,printf中的三条语句就不会换行输出,只显示在一排。
(2)#include <stdio.h>
void main()
{
int a=100,b=20,sum,sb;
sum=a+b;
3
sb=a/b;
printf("sum=%d,sb=%d",sum,sb);
}
运行结果及分析:
运行结果:
sum=120.sb=5
分析:
1.这是一个关于数的简单加法计算和除法计算并显示出结算结果的c程序; 一个c程序中必须只能有一个main函数,void main()是指子最后不给程序返回任何值;
2.用int将变量定义成了整型变量;
3.在定义变量时就将a和b初始化了值用于后面计算;
4.将a和b的和赋值到了sum中,将a和b 的商赋值到了sb中,并显示输出;
5.%d是指输出的时候是输出整数型
(3)#include <stdio.h>
void main( )
{
char c1,c2;
c1=97;c2=98;
printf("%c ,%c\n",c1,c2);
printf("%d,%d\n",c1,c2);
printf("%c %c\n",c1+1,c2+2);
}
运行结果及分析:
运行结果:
a b
97, 98
c, d
分析:
1.一个c程序中必须只能有一个main函数,void main()是指子最后不给程序返回任何值;
2.用char将c1和c2定义成字符变量,并给其赋值;所以;
3.用printf("%c ,%c\n",c1,c2)输出c1和c2所对应的字符,而97、98所对应的ASCII值是a和b
4. 用printf("%d,%d\n",c1,c2)输出所对应的值;
5. printf("%c %c\n",c1+1,c2+2)是指将c1和c2中的值加上1和2后所对应的字符值输出。
(4)#include <stdio.h>
void main ()
{
int i=8,j=10,m,n;
m=++i;n=j++;
} printf("%d,%d,%d,%d",i,j,m,n);
4
运行结果及分析:
运行结果:
9,11,9,10
分析:
1.一个c程序中必须只能有一个main函数,void main()是指子最后不给程序返回任何值;
2.用int将i,j,m,n定义成整型变量;
3.m=++i是指将i加1后赋值给m和i,n=j++是指先将j的值赋给n,然后j=j+1;
4.用printf("%d,%d,%d,%d",i,j,m,n)显示输出各变量所对应的值。
再将本程序的第3行改为m=i++;n=++j;
运行结果及分析:
运行结果:
9,11,8,11
分析:1.一个c程序中必须只能有一个main函数,void main()是指子最后不给程序返回任何值;
2.用int将i,j,m,n定义成整型变量;
3.m=i++是指先将i的值赋给m,然后i=i+1的值;n=j++是指将j+1的值赋给j和m;
4.用printf("%d,%d,%d,%d",i,j,m,n)显示输出各变量所对应的值。
2.程序填空
任意输入一个有五位数字的正整数x,分别输出每一数位上的数字(由高到低分别用b5,b4,b3,b2,b1表示),请将程序补充完整。
#include <stdio.h>
main()
{
int b1,b2,b3,b4,b5;
long int x;
Scanf( “ %ld ”,&x);
b5= (x/10000)%10 ;
b4=(x/1000)%10;
b3= (x/100) %10;
b2=(x/10)%10;
b1= x %10 ;
}
程序分析:
1.由于此程序要输出一个五位数,所以应将变量的类型定义成long int,以免超出范围后导致乱码输出;
2.scanf函数用于键盘输入,此命令将用户输入的值赋给x;
3.将输入的五位数的每一位的值通过运算公式转换成数,并用prinft函数显示输出。
3.程序改错(注意:题中的编号为行序号,并非程序本身)
计算任意一个半径为r的圆的面积和周长(结果保留两位小数)
(1)#include <stdio.h> printf(“the number is %ld \n”,x); printf(“its bit is:%d,%d,%d,%d,%d\n”,b5,b4,b3,b2,b1);
5
(2)main()
{
(3) float r; p=3.14,c,area;
(4) printf(“input r:”);
(5) scanf(“%f ”, r);
(6) c=2p*r;
(7) area=p*r*r
(8) printf(“c=%-7.2f,area=%-7.2f”,c,area);
(9)}
错误语句的行号: (3)
改正后的语句全行:float r, p=3.14, c, area;
错误语句的行号: (5)
改正后的语句全行: scanf(“%f”, &r);
错误语句的行号: (6)
改正后的语句全行: c=2*p*r;
错误语句的行号: (7)
改正后的语句全行:area=p*r*r;
改错分析:
1.在c程序中,一个语句中声明多个变量是需要用“,”隔开;
2.用scnf函数时,变量前面必须加操作符&,指明该变量的地址;
3.乘法表示要用*号表示;
4.每一个执行语句结束后必须用分号“;”结束。
6
实验二 逻辑运算和判断选取控制
(验证性实验 2学时)
(一)、实验目的
1.了解逻辑量在C语言中的表示方法
2.学会使用逻辑运算符和逻辑表达式
3.熟练掌握if语句和switch语句
(二)、实验内容
1.写出下列程序的运行结果
(1)#include <stdio.h>
void main( )
{
int a,b,x=10,y=9;
a=(--x == y++)? --x : ++y;
b= y;
printf(“%d,%d\n”,a,b);
}
运行结果及分析:
运行结果:
8,10
分析:
1. 此程序是关于逻辑运算符、递增和递减运算符以及条件运算符的应用;
2. void main()是指程序结束后不返回任何值;
3. int a,b,x=10,y=9;是定义int类型的整数变量及给想x和y初始化值;
4. a=(--x == y++)? --x : ++y;是指当x-1的值等于y的值时x=x-1,否则x=++y,因为
—x=9=y,所以条件成立,a的值就等于—x,而在前面的运算中x=9、y=10,因此—x=8;b=y=9;
5. printf函数显示输出所运算出来的结果。
(2)#include <stdio.h>
void main()
{
int a=2,b=-1,c=2;
If(a<b)
if(b<0)c=0;
else c+=1;
else
printf(“%d\n”,c);
}
运行结果及分析:
运行结果:
2
分析:
7
1. 此程序时关于if函数和c+=1类型的复合函数语句的应用;
2. 当if条件成立时就执行if下面的语句,不成立时则直接执行else语句,此程序中的
if(a<b)不成立,所以直接执行else c+=1;
3. c+=1;是指c=c+1,
(3)#include <stdio.h>
void main( )
{
int a=0,b=0,c=0;
if(++a > 0 || ++b > 0) ++c;
printf(“\na=%d,b=%d,c=%d”,a,b,c);
}
运行结果及分析:
运行结果:
a=1, b=0, c=1;
分析:
1. 此程序是关于if函数和递增运算符的应用;
2. int a=0,b=0,c=0;是定义整形变量并给其赋值;
3.if(++a > 0 || ++b > 0) ++c;是值当++a > 0 和 ++b > 0同时满足时,执行后面的++才,因为前面条件满足,所以执行++c;因此a=1,c=1,而因为在逻辑条件成立时,值进行前面的运算,所以b还是等于0;
4.Printf输出运算结果。
(4)#include <stdio.h>
void main()
{
int x=-1;
switch (x)
{
default: printf(“a”);
case 1: printf(“b”);
case 2: printf(“c”);
}
}
运行结果及分析:
运行结果:
abc
分析:
1. 此程序是关于switch语句的应用,在C语言中它经常跟Case一起使用,是一个判断选择
代码。其功能是控制业务流程流转的;
2. void main()是指程序结束后不返回任何值;intx=-1,是指定义整形变量并给其赋值; 8
3. 在switch()开始时,从default处开始执行,输出a,在往下执行,不满足case1,输
出b,再执行case2,也不满足,因此输出c。
在case 1:printf(“b”);后加上break;语句,结果如何?修改程序并上机调试。
运行结果及分析:
运行结果:
ab
分析:
1. 此程序是关于switch语句的应用,在C语言中它经常跟Case一起使用,是一个判断选择代码。其功能是控制业务流程流转的;
2. void main()是指程序结束后不返回任何值;intx=-1,是指定义整形变量并给其赋值;
3. 在switch()开始时,从default处开始执行,输出a在往下执行,不满足case1出c. 在遇到break时退出执行。
2.程序填空
输入两个整数,从用户处获取这两个整数,显示其中较大的数,在其后跟随“is larger”。如果这两个数相等,显示“These numbers are equal.”。请在_____内填入正确内容。
#include <stdio.h>
void main( )
{
int a,b;
printf(“please input two numbers, a, b! “);
scanf(“%d%d”,&a,&b);
if( a>b ) printf(“%d is larger”, a );
else if(______a=b________) printf(“These numbers are equal”);
else _____printf(“%d is larger”,b);
}
填空①:a>b
填空②:__a=b__
填空③: _printf(“%d is larger”,b);
结果分析:
运行结果:
5 is larger
分析:
1. 此程序涉及到了scanf键盘输入和if条件语句的应用;
2. scanf(“%d%d”,&a,&b)指用户输入两个数保存到a和b中;
3. if( a>b ) printf(“%d is larger”, a );
else if(______a=b________) printf(“These numbers are equal”);
else _____printf(“%d is larger”,b);指当a>b成立时输出a is larger,若a=b时输出These numbers are equal,若前面都不成立,a<b时,输出b is larger.;
9
3.编写程序
(1)编写一个程序,读入5个整数,然后确定并显示这组数中的最大整数和最小整数。 程序清单:
#include<stdio.h>
void main()
{
int max,min,x,n;
printf("please input the first number:");
scanf("%d",&x);
max=min=x;
for(n=2;n<=5;n++)
{
printf("please input the %d number:",n);
scanf("%d",&x);
if(x>max) {max=x;continue;}
if(x<min) min=x;
}
printf("the biggest number is:%d;the smallest number is:%d.\n",max,min); getch();
}
程序编写注意事项:
1. 此程序要连续输入五个数,可用for循环输出五条printf函数;
2. 五个数排列大小,在输入第一个数的时候这个数既是最大数也是最小数,在之后没输入一
个是数的时候就与前一个数进行比较,大的储存在max里,小的话就存在min里,直到第五个数比较完后输出结果,printf("please input the %d number:",n);
scanf("%d",&x);
if(x>max) {max=x;continue;}
if(x<min) min=x;实现了这个功能。
(2)编写程序,读取一个整数,判断并显示出这个整数是奇数还是偶数。(提示:使用求模运算符。偶数是2的倍数。任何2的倍数除以2时,余数均为零。)
程序清单:
#include <stdio.h>
void main()
{
int n;
printf("please input a number");
10
scanf("%d",& n);
if(n%2==0)
printf("This number is even number");
else
printf("This number is odd number");
getch();
}
程序编写注意事项:
1. 键盘输入函数不能丢掉位置控制符号&;
2. %是模运算符,取两数相处的余数;
3. 判断是奇数还是偶数要用条件运算符if。。else语句。
(3)编写一个程序,从键盘中输入3个不同的整数,然后显示这3个整数的和、平均数、积、最小数和最大数。(用if语句)屏幕中的对话内容如下所示:
程序清单:
#include <stdio.h>
void main()
{
int a ,b , c, m, n;
printf("Input three different integers:\n");
printf("Input first number:");
scanf("%d,",& a);
printf("Input scend number:");
scanf("%d,",& b);
printf("Input third number:");
scanf("%d,",& c);
printf("Sum is %d\n",a+b+c);
printf("Average is %d\n",(a+b+c)/3);
printf("Product is %d\n", a*b*c);
if(a>b && a>c)m=a;
else m=b;
if(b>c)m=b; 11
else m=c;
printf("Max is %d\n", m);
if(a<b)n=a;
else n=b;
if(b<c)n=b;
else n=c;
printf("Min is %d\n", n);
getch();
}
程序编写注意事项:
1. 函数要在main函数中进行定义,然后用scanf函数给定义好的三个变量赋值;
2. 对函数进行算术运算是要用c语言中特定的运算符,乘号用*表示,除号用/表示,括号代表
优先级运算;
3. 比较三个数大小的时候要用if..else条件函数进行比较;
4. 如果要在一条语句中显示,要注意c语言中的运算顺序。
12
实验三 循环结构程序设计(一)
(验证性实验 2学时)
(一)、实验目的
1.熟悉用while语句、do-wile语句和for语句实现循环的方法
2.掌握在程序设计中用循环方法实现的算法
(二)、实验内容
1.写出下列程序的运行结果
(1)#include <stdio.h>
void main()
{
int count=1;
while(count<=10)
{
}
}
运行结果及分析:
运行结果:
++++++++++
******
++++++++++
++++++++++
******
++++++++++
******
++++++++++
******
分析:
1. while是入口控制循环语句,先计算测试条件,如果该条件为真,那么就运行其循环体
语句,运行完后,再次计算测试条件,如果仍为真,则继续计算循环体,直到条件为假,所以在本程序中,直到将count++运行到count等于10时停止运算;
2. 在prinrf语句中,count%2是对count进行求模运算,并用?条件语句,当count%2
时输出******,否则就输出++++++++++。因为count一直循环到10,所以就各出了五次。
(2)#include <stdio.h>
void main()
{ ****** count++; printf(“%s\n”,count%2? “****”: “++++++++++”);
13
int row=10,Column;
while(row>=1) {
}
运行结果及分析:
运行结果:
>>>>>>>>>>>
<<<<<<<<<<< >>>>>>>>>>> <<<<<<<<<<< >>>>>>>>>>> <<<<<<<<<<< >>>>>>>>>>> <<<<<<<<<<< >>>>>>>>>>> <<<<<<<<<<<
1. while是入口控制循环语句,先计算测试条件,如果该条件为真,那么就运行其循环体语
句,运行完后,再次计算测试条件,如果仍为真,则继续计算循环体,直到条件为假;
2. while可进行循环的嵌套,在本程序中就进行了循环的嵌套,在第一个循环下,再进行
while循环,第二个循环是对Column进行求模和用?判断输出<>,一直循环到Column=10为止,第一个while循环是控制换行输出的,直到row>=1时退出循环。
(3)#include <stdio.h>
void main()
{
int y=9;
for( ; y>0 ; y--)
if(y%3==0) printf("%d\n" , --y);
}
运行结果及分析:
分析: } Column=1; while(Column <=10) { } row--; printf(“\n”); printf(“%s”,row%2 ? “<”: “>”); Column++;
14
运行结果:
8
5
2
分析:
1. for语句也是一种入口控制循环,在本程序中for( ; y>0 ; y--)是循环条件,先将y
初始化为9,每执行一次后面的循环体y就自减一次,知道y>=0是停止循环;
2. if(y%3==0) printf("%d\n" , --y);是循环体,意识是当y除以3没有余数时就输出
y-1的值;
3. 该程序是关于for循环和求模运算的应用。
2.编写程序
(1)利用循环语句来显示如下所示的数值表:
程序清单如下:
#include <stdio.h>
void main()
{
int n;
printf("N\t10*N\t100*N\t1000*N\n") ;
n=1;
while(n<=10)
{printf("%d\t %d\t %d\t %d\n ",n,10*n,100*n,1000*n );
n++;
}
getch();
}
程序编写注意事项:
1. 此程序的输出要用到循环语句,可以选择用for循环或者while循环;
2. 在编写程序时考虑到格式的美观可以用\t使各个数之间保持一定的间距。
15
(2)编写一程序,能够输入一组10个数字,判断并显示出这些数字中的最大数。提示:程序中应该使用如下的3个变量:
Counter:能够记数到10的记数器。
Number:当前输入到程序中的数字。
Largest:迄今为止所发现的最大数字。
程序清单:
#include <stdio.h>
void main()
{
int Counter, Number, Largest;
printf("please input the first number:");
scanf("%d", & Number);
Largest=Number;
for(Counter=2;Counter<=10;Counter++)
{
printf("please input the %d number:",Counter);
scanf("%d", & Number);
if(Number>Largest) Largest=Number;
else Largest=Largest;
}
printf("the largest number is %d", Largest);
getch();
}
程序编写注意事项:
1. 首先要定义好所需要的三个变量,即Counter:能够记数到10的记数器,Number:当前输入
到程序中的数字和Largest:迄今为止所发现的最大数字;counter在循环时用来计数,number存储从键盘输入的数字,largest就是用来存储比较后最大的那个数字;
2.
此程序涉及到循环输出和比较大小,所以就要用for或者while语句来是想循环,且在循环是要注意没输入一个数时(第一个数除外)都要和之前输入的数进行比较,比较时就要用到if条件语句。
3. 要注意printf语句的位置,是在循环输入和比较之后再进行输出。
(3)请开发一个程序来输入每油箱的行程里程和所用的汽油。能够计算并显示出对于每个油箱每加仑汽油的行驶里程。处理输入信息后,计算并显示所有油箱每加仑汽油的行驶里程。以下是一个事例的输入/输出:
16
程序清单:
#include <stdio.h>
void main()
{
float Gallon,Miles;
printf("Enter the gallons used <-1 to end>:") ;
scanf("%f", &Gallon);
printf("Enter the miles driven:");
scanf("%f", &Miles);
printf("The Miles/Gallon for this tank was %f",Miles/Gallon) ;
getch();
}
程序编写注意事项:
1. 在定义 Gallon和Miles这两个变量时要定义成实数浮点型;
2. 在用printf显示输出信息后就要用scanf函数输入相对应的函数;用scanf输入数字时要
注意不要掉了地址控制符。
(4)编写一个程序读入一个5位数,并判断该整数是否是回文。(回文指顺读和倒读都一样的数字和文字语句,例:12321,55555。)提示:使用除法运算符和求模运算符把该数分解成单位个数。
程序清单:
#include <stdio.h>
main()
{
int b1,b2,b3,b4,b5;
long int x;
scanf( " %ld ",&x);
b5=(x/10000)%10;
b4=(x/1000)%10;
b3=(x/100)%10;
b2=(x/10)%10;
17
b1= x %10;
if(b1==b5,b2==b4)
printf("the number %ld is huiwen",x);
else
printf("the numbe %ld is not huiwen", x) ;
}
程序编写注意事项:利用整除和取模运算计算出每一位上的数字,然后将第一项和第五项,第二项和第四项比较,显示其结果。
18
实验四 循环结构程序设计(二)
(验证性实验 2学时)
(一)、实验目的
1.熟练掌握循环语句。
2.较灵活地运用三种不同循环语句实现循环程序设计。
3.熟练掌握break语句、continue语句及循环的嵌套使用。
(二)、实验内容
1. 写出下列程序的运行结果
(1)#include <stdio.h>
void main()
{
int i,j,k,x=0;
for(i=0;i<2;i++)
{
x++;
for(j=0;j<3;j++)
{
if(j%2) continue;
}
x++;
}
k=i+j;
printf("k=%d,x=%d\n" , k , x);
}
运行结果:
k=5,x=8
程序分析:
1. 此程序是关于for循环嵌套的应用,外循环for(i=0;i<2;i++)是指给x赋值为0,
循环一次后x=x+1,直到x等于2时停止,是将{}里面的内容进行循环。
2. 内循环for(j=0;j<3;j++)是给j赋初始值值为0,直到j等于3时停止循环,循环
体为if(j%2) continue; x++;
3. 在内循环中的if条件语句,是指当j对2求模运算余数为0时继续进行循环,否
则就退出循环,
4. 因为在循环结束后i=2,j=3,所以k=5,x++运行了8次,所以x=8.
x++;
19
(2)#include <stdio.h>
void main()
{
int x,y;
for(y=1,x=1;y<=50;y++)
{
if(x>=10) break;
if(x%2==1) { x+=5; continue;}
x-=3;
}
printf(“x=%d,y=%d\n”,x,y);
}
运行结果:
X=10,y=6
及分析:
1. 此程序也是关于for循环和if条件判断语句的应用;
2. for(y=1,x=1;y<=50;y++)是指给x和y初始化值为1,在每次循环后加上1,直到y的
值<=50后停止循环;
3. 在循环体中的if(x>=10) break;是指当x>=10时停止跳出循环,if(x%2==1) { x+=5;
continue;}是指当x的值与2进行求模运算余数为1是进行x+=5的运算并继续,进行x-=3的运算x的变化过程为:6,3,8,5,10;
4. 因为x>=10时停止了循环,所以x=10,总共循环了5次,y的初始值为1,所以y最后
的值为6.
(3)#include <stdio.h>
void main()
{
int i , j , sum;
for(i=1;i<6;i++)
{
sum=0;
for(j=1;j<=4;j++)
sum+=j;
}
printf(“sum=%d\n”, sum);
}
运行结果:
Sum=10
分析:
1. 此程序是关于for循环结构的嵌套使用;
2. 外循环for(i=1;i<6;i++)将i初始为1,直到i的值等于6时停止循环;
3. 内循环for(j=1;j<=4;j++)将j的值初始为1,直到j的值等于4时停止循环,sum+=j 20
时指sum=sum+j;
4. 虽然外循环了6次,但每次在进行内循环时都将sum的值初始为0了,所以最后结果
j=10.
(4) #include <stdio.h>
void main ( )
{
int k = 0 , m = 0 , i , j;
for( i = 0 ; i < 2 ; i++)
{
for ( j = 0 ; j < 3 ; j++)
k++;
k -= j;
}
m = i + j;
printf("k=%d,m=%d\n",k,m);
}
运行结果:
k=0,m=5
分析:
1. 此程序是关于for循环结构的嵌套使用;
2. 外循环for( i = 0 ; i < 2 ; i++)是指将内循环进行两次循环,内循环是指将k++; k -= j;进行三次循环;
3. j循环中:k的值变化为:1,1,2,1,2,0.循环两次结果不变,所以k的值就为0,在循环结束后i和j的值分别为2和3,所以m的值为5
2. 程序填空
(1)下面程序的功能是:输出100以内同时能被3和7整除的所有整数,请填空。
#include <stdio.h>
void main()
{
int i, j;
for ( i=1;___①_____; i++ )
{
if (___②______) continue;
printf ( "%d\t",i );
}
}
填空①:i<=100;
填空②:i%3&&i%7
程序分析:
1)、此程序是关于for循环结构和if判断的应用;
2)、在for循环中,i=1是给循环变量赋初始值为1,i<=100;是循环条件,因为要计算 21
1到100直接能被3和7整除的数,所以要条件要<=100.i++是循环一次后进行自增运算;
3)、判读一个是是否同时被3和7整除,要用模运算和逻辑运算符实现,即i%3&&i%7,并且当判断这个条件成立时将数输出。
(2)判断m是否素数
#include <stdio.h>
void main()
{
int m,i,k;
scanf(“%d”,&m);
for(i=2;i<m;i++) if(__m%i==0_____) break;
if(i>=m)printf(“%d是一个素数\n”,m);
else printf(“%d不是一个素数\n”,m);
}
填空:m%i==0
并运行分析:
1)、此程序是关于for循环结构和if判断的应用;
2)、素数是只能被1和它本身整除的数,所以在进行一个数是否是素数的时候,就判断是否能被2和数本身-1整除,如果可以就不是素数,反之就是,for(i=2;i<m;i++) if(__m%i==0_____) break;就是将一个数和2到本身减1进行模运算,为0时退出,并输出不是素数,不等于0是输出是素数。
3. 编写程序
(1)编写一个程序,能够找出几个整数中最小的整数。假定程序读取的第一个值是余下数值的数目。
程序清单:
#include <stdio.h>
void main()
{
int i,n,low=0 ;
printf("please input a number:\n");
scanf("%d",&n);
low=n;
for(i=1;i<=4;i++)
{
printf("please input a number:\n");
scanf("%d",&n);
if(low<n)
{
low=low;
}
else
22
{
low=n;
}
}
printf("the smallest number is %d",low);
getch();
}
程序编写注意事项:
1、 读取多个数据时为了方便要使用循环语句;、
2、 在对输入的数据进行比较时,将第一个数据赋给low、然后再将low与后面每输入一个
就进行比较一次,每比较一次就将较小的值赋给low,直到最后输出。
(2)编写一个程序显示出如下菱形图案。可以使用printf语句来显示一个(*)和一个空格,尽量多使用循环语句(嵌套的for语句),尽量少用printf语句。
程序清单:
#include <stdio.h>
#define N 5
void main()
{
int i,j ;
for(i=1;i<=N; i++)
{
for(j=1;j<=N-i;j++)
{
printf(" ");
}
for(j=1;j<=2*i-1;j++)
{
printf("*");
}
printf("\n") ;
}
i=4,j=0;
for(;i>=1;i--)
{
for(j=1;j<=5-i;j++)
{
23
printf(" ");
}
for(j=1;j<=2*i-1;j++)
{
printf("*");
}
printf("\n") ;
}
getch();
}
程序编写注意事项:
1. 此程序要用到fou循环的多重嵌套;
2. 在显示上半部分正三角形时for循环的行数计数器是从1递增到5,每行显示的空格的个
数用最大行数减去当前行数,输出的“*“号个数用公式2*N-1计算出来;
3. 在显示下半部分倒三角形时for循环行数从最大行递减到1,每行空格个数用N-当前行数。
*号个数还是用2*N-1计算出来,这时的*号个数是递减的。
(3)输入从1994~1999这个范围内的年份,并使用for循环语句来生成一个简洁的日历。注意闰年的情形。
程序清单:
#include <stdio.h>
#include<conio.h>/*--控制台输入输出函数--*/
#include<stdlib.h>
int IsLeapYear(int);/*--判断某一年是否为闰年--*/
void main()
{
int i;
int day;
int year;
int temp;
int temp_i;
long int Year_days = 0;
int Year_Start = 1;
int Per_Year_Days;
int month_day[]={31,28,31,30,31,30,31,31,30,31,30,31,29}; /*-一年每个月的天数--*/
printf("Please enter the year(form1991-1994): ");
scanf("%d",&year);
/*--从公元1年开始执行循环,因为该年的一月一号为星期一,用某年的某天与这天相差的 天数与7求余数知道是星期几---*/
while(Year_Start < year)
{
/*---如果是闰年则为366天,否则就为365天---*/
if( IsLeapYear( Year_Start ) )
24
Per_Year_Days = 366;
else
Per_Year_Days = 365;
/*---从公元1年到输入年份的前一年的天数的总和--*/ Year_days = Year_days + Per_Year_Days; Year_Start++;
}
/*--tmp为从1到12,对应每年的12个月--*/ for( temp = 1; temp <=12; temp++ )
{
switch( temp )
{
case 1:
printf(" January(%d)\n",year);
break;
case 2:
printf(" February(%d)\n",year);
break;
case 3:
printf(" March(%d)\n",year);
break;
case 4:
printf(" April(%d)\n",year);
break;
case 5:
printf(" May(%d)\n",year);
break;
case 6:
printf(" June(%d)\n",year);
break;
case 7:
printf(" July(%d)\n",year);
break;
case 8:
printf(" August(%d)\n",year);
break;
case 9:
printf(" September(%d)\n",year);
break;
case 10:
printf(" October(%d)\n",year);
break;
case 11:
printf(" November(%d)\n",year);
25
break;
case 12:
printf(" December(%d)\n",year);
break;
}
/*---每个星期有七天,所以用每年的天数对7取余求是星期几--*/
i = Year_days % 7;
printf("Mon Tue Wed Thu Fri Sat Sun\n");
if( i != 0 )
for( temp_i = 0; temp_i < i; temp_i++)
printf(" ");
day = 1;
if( IsLeapYear(year) && temp == 2)
while( day <= month_day[12] )/*---去一年365天的值,是闰年则为366天-*/ {
if( day >1 )
if( Year_days % 7 == 0 )
printf("\n");
if( day >= 10 )
printf("%d ",day);
else
printf("%d ",day);
Year_days++;
day++;
}
else
while (day <= month_day[temp-1])
{
if( day > 1 )
if( Year_days % 7 == 0 )/*--如果是星期日则换行--*/
printf("\n");
if( day >=10 )
printf("%d ",day);
else
printf("%d ",day);
Year_days++;
day++;
}
printf("\n");
if( getch() == 'q' )
exit(0);
} getch();
/*--判断是否是闰年,是则返回1,不是则返回0*/
26
} int IsLeapYear( int year )
{ if ((year %4 == 0) && (year % 100 != 0) ||
(year % 400 == 0) )
return 1;
else
return 0;
程序编写注意事项:
1. 编写此程序时要用到控制输入输出的函数,所以在开始要调用预定义文件中的函数;
2. 判断一年是否是闰年要用到IsLeapYear()函数,判断某一天是星期几要用时间函数或者进
行计算;
27
实验五 函数
(验证性实验、综合性实验 2学时)
(一)、实验目的
1.掌握定义函数的方法
2.学会利用函数的相关概念解决问题
3.学会使用函数的方法设计程序
(二)、实验内容
1.写出下列程序的运行结果
(1)#include “stdio.h”
f(int x, int y);
void main()
{
int a=1,b=2;
f(a,b);
printf(“%d,%d\n”,a,b);
}
f(int x,int y)
{
x=x+1;
y=y+1;
}
运行结果:
1,2
分析:
1、 在main函数之前进行了一个自定义函数的声明,该函数默认为int类型,有两个形参
变量,在main函数后进行了函数的定义,将两个变量的值各自加1,不返回值;
2、 在main函数中定义了两个整形变量并分别赋值为1,2.然后调用f(),将a和b的值
传到函数中进行运算,但是因为在调用函数时并没有返回值,所以调用完之后a和b中还是原来的值。
(2) #include <stdio.h>
fun(int a);
void main()
{
int a=3;
fun(a);
printf("%d\n",a);
}
fun(int a)
{
a=a+3;
printf("%d,",a);
28
}
运行结果:
6,3
分析:
1、 在main函数之前进行了自定义fun()函数的声明,在main函数哈进行了函数的
定义,函数的功能是将调用函数时的值加上3再付给原变量,然后输出该变量的值;
2、 在main函数中进行了函数调用,调用时传值为3,因为调用函数没有返回值,因此
在函数调用结束之后,a的值还是3.
(3)#include <stdio.h>
int fun(int x)
{
static int a=3;
}
void main()
{
int k=2,m=1,n;
n=fun(k);
n=fun(m);
printf(“%d\n”,n);
}
6
分析:
1、 在main函数之前进行了fun函数的定义,在fun函数中将a定义成了静态变量,所以
只将a的值在每次调用fun函数时只将a的值初始化一次,且每次计算过后的值都保留在函数的a当中;
2、 在main函数中,第一次调用时将k的值的副本传递到fun函数,计算后a=5,返回a
的值赋给n,第二次调用时将m的值的副本传递给fun函数进行计算,因为a时静态变量,值还是5,所以计算后的结果就为6。
(4) #include <stdio.h>
float fac(int n)
{
float f;
}
void main()
{
int n=4; if(n<0)printf(“error!”); else if(n==0||n==1) f=1; else f=fac(n-1)*n; return(f); 运行结果: a=a+x; return a;
29
float y;
y=fac(n);
printf(“%d!=%f\n”,n,y);
}
运行结果:
结果分析:
1、 此程序是用函数的迭代来实现计算一个数的阶层;
2、 在main函数之前自定义了一个函数,函数中先判断接受进来的数是否小于0,若小
于0就显示错误,等于0或1 时返回1,大于1时调用函数自身计算阶层;
3、 在main函数中定义x并初始化为4,传递到fun函数中进行计算后将返回值赋给y
并显示。
2. 程序填空
(1) 通过调用函数求a+b的和。
#include <stdio.h>
float add(float x,float y);
void main()
{
float add(float x,float y);
float a,b,c;
scanf(“%f,%f”,&a,&b);
c=_ ____ add(a,b)_________;
printf(“%f”,c);
}
float add(float x,float y)
{
float z;
z=x+y;
return z;
}
填空: add(a,b) 运行结果:
分析:
1、 在主函数之前进行了自定义函数的声明,在main函数中定义三个实数,从键盘
读取两个值到x和y中,调用add函数将x和y的值传递过去进行计算并将返回的值付给c;
2、 在add函数的定义中,将返回值类型定义成float类型,并将计算后的值返回。
(2)从键盘输入任意一个数,用函数计算它的阶乘
#include <stdio.h>
long int f(int a)
30
{
long int i,t=1;
for(i=1;i<=a;i++)
t=t*i;
return_(t)___;
}
void main()
{
long int x;
scanf(“%ld”,&x);
printf(“%ld”,f(x));
}
填空: return_(t)___;
运行分析:
1. 在自定义函数中,用for循环来实现一个数的阶层的计算,用t来保存计算后的
值,计算完后将t的值返回给主函数;
2. 在主函数中,定义一个变量,从键盘读取之后传递到自定义的f函数中,并将返
回值显示出来,在编程时最好将返回值类型设置成长整型以便用来存储正确的数
值。
3.编写程序
(1) 编写函数floor,把值四舍五入为最近的整数。语句:y = floor + ( x + .5) ;将把x 四舍五入为最近的整数,并存如 y 。要求读取几个整数,并使用前面的语句把每个数字四舍五入为最近的整数。对于程序中处理的每个整数,显示出原始数字和四舍五入后的数字。 程序清单:
#include <stdio.h>
int floor(float n);
main()
{
int i=0,s;
float m;
for(i=0;i<=3;i++)
{
m=0;
printf("Input a float number:");
scanf("%f",&m);
s=floor(m);
printf("%d\n",s);
}
getch();
}
int floor(float n)
{
int p;
p=n+0.5
31
return(p);
}
程序编写注意事项:
1、 在main函数前先进行floor函数的声明;
2、 定义float型变量用sanf函数读取需要进行四舍五入的数,调用floor函数时传递值
3、 在main函数后进行floor函数的定义,因为传递过去的值为float类型,在加上0.5
后取整就是四舍五入后的值
(2) 实现下列每个整型函数。
a)函数 Celsius 返回与华氏温度等价的摄氏温度。
b)函数 Fahrenheit 返回与摄氏温度等价的华氏温度。
c)使用这两个函数编写程序,使其显示一些图表,图表中显示从0度 ~ 100度之间的所有摄氏温度的华氏温度等价值,以及从32度 ~ 212 度之间的所有华氏温度的摄氏温度等价值。按照见解的表格形式来显示输出结果,在保留可读性的同时使输出的行数最小。
程序清单:
#include <stdio.h>
#define LOW 32
#define MAX 212
float Celsius(float fah);
float Fahrenheit(float cels);
void main()
{
int i,j;
float fahrenheit,celsius;
/*--从华氏到摄氏--*/
printf("Fahrenheit Celsius\n\n");
for(i=0;i<=100;i++)
{
celsius=Celsius(i*1.0);
printf(" %d %7.2f\n",i,celsius);
}
/*---从摄氏到华氏---*/
printf("Celsius Fahrenheit\n\n");
for(j=LOW;j<=MAX;j++)
{
fahrenheit=Fahrenheit(j*1.0);
printf(" %d %7.2f\n",j, fahrenheit);
}
getch();
}
float Celsius(float fah)
{
float p;
p=(fah-32.0)/1.8;
32
return(p);
}
float Fahrenheit(float cels) {
float p;
p=(9*cels)/5+32;
return(p);
}
程序编写注意事项:
33
实验六 数组(一)
(验证性实验 2学时)
(一)、实验目的
1.掌握一维数组的定义,赋值和输入输出的方法。
2.掌握二维数组有关的定义,赋值和输入输出的方法。
3.掌握与数组有关的非数值计算方法。
(二)、实验内容
1.写出下列程序的运行结果。
(1) #include <stdio.h>
void main()
{
int a[3]={1,2};
int i,j;
for(i=0;i<3;i++)
}
运行结果:
2
3
1 2 for(j=0;j<3;j++) { } a[i]=a[j]+1; printf("\n%d",a[i]);
3
1
2
2
3
结果分析:
1、 此程序是关于数组的运用,涉及到数组的定义及初始化值,数组在进行定义和赋值
时要注意到元素是从0开始,且要留一个位置储存结束标记,如果赋值的个数少于数组大小,则后面的都默认为0;
2、 数组的每一个元素可以参加运算,此程序就是用for循环将每一个元素依次和每一
个元素相加。
(2)#include <stdio.h>
#define N 20
fun(int a[],int n,int m)
{
int i,j;
for(i=m;i>=n;i--)
34
a[i+1]=a[i];
}
void main()
{
int i,a[N]={1,2,3,4,5,6,7,8,9,10};
fun(a,2,9);
for(i=0;i<5;i++)
printf("%d,",a[i]);
}
运行结果:
12334
分析:
1、 此程序既有关于数组的应用,也有关于函数的应用;
2、 Fun()所定义了一个函数,这个函数的作用是将a[]数组里的元素从m个元素起,把前
一个元素的值赋给后一个,到第n个元素时结束;
3、 在main函数后定义了一大小为20的数组,并给前十个赋值,调用fun函数后输出前
五个元素的值,因为在调用过程中只将元素值改变到第四个,所以a[2]=a[3],因此结果为上图显示。
(3)#include <stdio.h>
void swap1(int c[])
{
int t;
t=c[0];c[0]=c[1];c[1]=t;
}
void swap2(int c0,int c1)
{
int t;
t=c0;c0=c1;c1=t;
}
void main( )
{
int a[2]={3,5},b[2]={3,5};
swap1(a) ;
swap2(b[0],b[1]);
printf("%5d %5d %5d %5d ",a[0],a[1],b[0],b[1]);
}
运行结果:
5 3 3 5
分析:
1、 此程序也是关于函数和数组的综合应用;
2、 自定义Swap1函数的作用是定义一个数组,定义一个整型变量,将变量t的值赋给数
组里的第一个元素,第一个元素赋给第二个元素,第三个元素赋给t;
3、 自定义swap2函数的作用是定义三个变量,将t的值赋给c1,c1的值赋给c2,c2的 35
值赋给t,但是因为在调用函数时是备份了数组元素中的值,而函数调用过程中并没有返回值,所以原数组中的值没变;
4、 Main函数是调用两个自定义函数,并且分别显示两个数组的前两个元素。
2.程序填空
(1)将Fibonacci数列前15项放入一个一维数组中(fib[0]=1,fib[1]=1),并计算其中奇数之和。
#include <stdio.h>
void main()
{
int fib[15],i,s=0;
fib[0]=1;
fib[1]=1;
for(i=2;i<15;i++)
① ;
for(i=0;i<15;i++)
if( ② )s=s+fib[i];
printf("%d\n",s);
}
填空①:fib[i]=i;
填空②:i%2==1;
程序分析:
此程序是一个关于数组的定义、赋值及运算的问题,定义一个大小为15的数组,将每一个数组里依次装好想对应的值,利用与2求模运算来判断是否为奇数,如果是就将其与s相加,计算总奇数的和
(2)给出以下形式数据,计算各行之和,并存入一个一维数组中。
124
615
800
#include <stdio.h>
void main()
{int a[3][3]={{1,2,4},{6,1,5},{8,0,0}},b[3]={0};
int i,j;
for(i=0;i<3;i++)
for(j=0;j<3;j++)
① ;
for(i=0;i<3;i++)
printf("%6d", ② );
}
填空①:b[i]=b[i]+a[i]a[j];
填空②:b[i]
程序分析:
1、 此程序涉及到了二维数组的定义、赋值与运算;
36
2、 int a[3][3]={{1,2,4},{6,1,5},{8,0,0},定义一个大小为9的二维数组并分别给每
行每列赋值,b[3]是用来存每行的和的;
3、 前两个for循环是用来计算每行的和的,后面的for循环是现实b[3]的值。
3. 编写程序
(1)已知数组a[10]={3,7,6,5,4,1,2,9,9,7},计算数组下标为奇数的元素之和。
程序清单:
#include <stdio.h>
void main()
{
int i;
int s=0,a[10]={3,7,6,5,4,1,2,9,9,7};
for(i=0;i<10;i++)
{
if(i%2==1)
{
s=s+a[i];
}
}
printf("%d",s);
getch();
}
程序编写注意事项:
此程序在编写时要注意数组的定义与赋值,在进行奇数项运算时循环的计数器应从0开始,条件要<10.奇数项判断要用取模运算。
(2)使用数组解决下列问题。公司在对销售人员支付佣金。销售人员每个星期收到$200,以及那个星期他们总销售额的9%。例如,在某个星期中销售额为$3000的销售人员收到$200以及$3000的9%,也就是$470。编写一个程序(使用计数器数组),确定销售人员在下列范围内可以赚取的收入(假定每个销售人员的工资将截断为整数):
a) $200 -$299
b) $300 -$399
c) $400 -$499
d) $500 -$599
e) $600 -$699
f) $700 -$799
g) $800 -$899
h) $900 -$999
i) $1000 以及$1000以上
程序清单:
#include <stdio.h>
main()
{
37
int sales[9][2];
int pay[9][2],i,j;
sales[0][0]=200,sales[0][1]=299;
for(i=0;i<=9;i++)
{
for(j=0;j<2;j++)
{
pay[i][j]=sales[i][j]*0.09+200;
sales[i+1][j]=sales[i][j]+100;
}
}
for(i=0;i<9;i++)
{
printf("\n%d-%d should pay %d-%d",sales[i][0],sales[i][1],pay[i][0],pay[i][1]); }
printf("\nif you sales more than 1000,you can get more than %d\n",pay[8][0]); getch();
}
程序编写注意事项:
1、 定义数组时要定义足够大的空间用来储存销售人员的成果;
2、 注意确定工资范围的算法,将每个人的销售成绩乘以0.09后就上200与100进行整除
确定范围,并在相应的数组中加上1;
3、 显示时范围的输出和算法;
(3)使用二维数组来解决下列问题。公司与4个销售人员(1 ~ 4),他们销售5种不同的产品 (1~
5)。每天,每个销售人员为销售的每种不同产品上交报告。每份报告包括:
a) 销售人员编号。
b) 产品编号。
c) 当天每种产品的总销售额。
因此,每个销售人员每天上交0~5份销售报告。假设已经知道上个月所有报告的信息。编写一个程序读取所有这些信息,以得到上个月的销售额,并对销售人员按产品来计算总销售额。所有总和必须存储在二维数组sales中。在处理了上个月的所有信息之后,以列表形式输出结果,其中列代表特定的销售人员,而行代表特定的产品。计算每行的总和,以得到上个月每个销售人员的销售总额。输出结果应该在每行的右边显示产品销售总和,在每列的底部显示个人销售总和。 程序清单:
#include <stdio.h>
#define MAX 5
#define MAXS 4
void main()
{
int products[5]={1,2,3,4,5},mproduct[4];
int sales[MAX][MAXS];
int i,j;
38
/*按产品种类输入每个人的销售成绩*/
printf("Input products sold by every people:");
for(i=0;i<5;i++)
{
for(j=0;j<4;j++)
{
scanf("%d",&sales[i][j]);
}
}
/*计算每个人的全部销售成绩*/
for(j=0;j<4;j++)
{
mproduct[j]=0;
for(i=0;i<5;i++)
{
mproduct[j]=mproduct[j]+sales[i][j];
}
}
/*显示整个报告表*/
printf("\tM1\tM2\tM3\tM4\n");
for(i=0;i<5;i++)
{
printf("%d\t",products[i]);
for(j=0;j<4;j++)
{
printf("%d\t",sales[i][j]);
}
printf("\n");
}
for(j=0;j<4;j++)
{
printf("\t%d",mproduct[j]);
}
getch();
}
程序编写注意事项:
1、 此程序因为要显示每个销售人员的每种产品的成绩因此要用到二维数组, 在读取输入的
数据到二维数组时要应用for循环进行录入;
2、 计算每位职员的总成绩时需要定义另外一个数组储存相对应的总值,在最后用for循环
将结果输出,并且以报表的格式输出。
39
实验七 数组(二)
(验证性实验 2学时)
(一)、实验目的
1. 掌握字符数组的定义、赋值和引用
2. 字符串函数的使用。
(二)、预习内容
1.预习数组的定义、赋值及输入输出方法,以及典型的算法。
2.熟练循环语句与数组处理语句结合的方法。
(三)、实验内容
1. 写出下列程序的运行结果
(1)#include <stdio.h>
void main()
{
char a[10]= "abcdefg",b[ ]="abcdefg";
a[3]=’\0’;
b[3]=0;
printf("%d,%d",sizeo f(a),strlen(a));
printf("%d,%d",sizeof(b),strlen(b));
}
运行结果:
10,3,10,3
分析:
1、 此程序中定义了两个字符串数组,并分别给其中的元素用双引号赋值;
2、 给a数组的第四个元素赋值为空字符,b数组的第四个元素赋值为整数0;
3、 Sizeof函数是显示整个数组的长度,strlen函数是显示数组中字符串的长度,因为a数
组中的第四个元素赋值为空字符结束标记,所以字符串长度为3,而b数组的第四个赋值为数据类型的0,所以其中的字符串长度为3.
(2)#include <stdio.h>
void main()
{
char ch[2][5]={"6937","8254"};
int i,j,s=0;
for(i=0;i<2;i++)
for(j=0;ch[i][j]>'\0'&&ch[i][j]<='9';j+=2)
s=10*s+ch[i][j]-'0';
printf("%d\n",s);
}
运行结果:
6385
分析:
1、 将ch定义为一个2行5列的字符串数组,并给每一个元素赋值;
40
2、 for(i=0;i<2;i++)
for(j=0;ch[i][j]>'\0'&&ch[i][j]<='9';j+=2)
s=10*s+ch[i][j]-'0';用for循环判断数组中的字符,不等于空字符和小于9的ASCII码时就将此字符的ASCII码加上10与s的乘积,减去字符0是将字符数字转换为相应的整数值。
(3)下列程序的输出结果是:
#include <stdio.h>
void main( )
{
char p1[20]="abcd",p2[20]="ABCD",str[50]="xyz";
strcpy(str+2,strcat(p1+2,p2+1));
printf("%s",str);
}
运行结果:
结果分析:
1、 此程序是关于字符串函数的应用,strcat函数的作用是将两个字符串连接起来,
strcat(p1+2,p2+1)的执行:p1=“abcd”,由于p1指向其首地址a,所以p1+2指向的是c,同理,p2+1指向的是B,所以结果为cdBCD;
2、 strcpy(str+2,strcat(p1+2,p2+1))的执行:str[50]=”xyz”,由于str指向"xyz"的首
地址'x'的地址,所以str+2指向'z'的地址,所以,strcpy(str+2,"cdBCD")也就是将"z"用"cdBCD"进行字符串拷贝,拷贝后,原有的以'z'为起始的空间被"cdBCD"覆盖,而前面的"xy"不受影响。
2. 程序填空
(1)将一个字符串按逆序重新存放,并输出。
#include <stdio.h>
void main()
{
char a[20];
int n,i,t;
gets(a);
① ;
for(i=0;i<n/2;i++)
{_ ②_ _____}
puts(a);
}
填空①:n=strlen(a);
填空②:t=a[i];
a[i]=a[n-1-i];
a[n-1-i]=t;
41
程序分析:
1、 此程序涉及到字符串函数计算串长度srtlen()的应用,gets读取一整行字符串,strlen
函数计算读取的字符串长度,这个长度作为for循环调换元素的值时的循环条件;
2、 需要注意的是在逆转元素的值时,要定义一个中间变量,而且因为数组的下标是从0开
始的,所以要用字符串长度-1后再减i与下标为i的对应。
(2)以下程序中函数huiwen的功能是检查一个字符串是否是回文,当字符串是回文时,函数返回字符串:yes!,否则函数返回字符串:no!,并在主函数中输出.(所谓回文即正向与反向的拼写都一样,例如:adgda).请填空.
#include "string.h"
#include <stdio.h>
int huiwen(charstr[])
{
int p,i,j;
p=strlen(str);
for(i=0,j=p-1;i<j; )
if( ① ) return 0;
return 1;
}
void main()
{
char str[50];
printf("Input:");
scanf("%s",str);
if( ② ) printf("yes!");
else printf("no!");
}
填空①:str[i]==str[j]
填空②:huiwen(str)==0
程序分析:
1、 程序因为要用到字符串函数,所以调用了string库文件;
2、 自定义了一个函数,先计算出输入字符串的长度,用for循环和if条件语句实现首
尾相对应的元素的比较,如果相等返回0.继续比较,不相等返回1退出循环;
3、 在main函数中,当自定义huiwen()返回的值是0时就输出yes,是1的话就输出
no
42
3. 程序改错
写出有错误语句的行号,及改正后的语句全行。(每行语句前的序号只标注行号,非程序本身的内容)
(1)以下scpy( )函数实现字符串复制,即将t所指字符串复制到s所指向内存空间中,形成一个新的字符串s。请填空。
① #include <stdio.h>
② void scpy(char s[ ],char t[ ])
{
int i;
while(t[i])
s[i++]=t[i++];
t[i]=‘\0’; ③ ④ ⑤ ⑥
} {
char str1[ ],str2[ ]="abcdefgh";
scpy(str1,str2);
printf("%s ",str1); ⑦ void main( ) ⑧ ⑨ ⑩
}
错误语句的行号:③、④ 、⑥、⑧
改正后的语句全行:
③、int i=0;
④、while(t[i]!=’\0’)
⑥、st[i]=’\0’;
⑧、char str[20] ,str2[ ]="abcdefgh";
错误分析:
1、③语句的i在使用前应先初始化值;
2、④语句中的while语句是要实现t数组中的元素到结束标记时停止;
3、给s数组的最后一个元素赋值为结束标记;
4、在定义数组时如果没有赋值,必须定义数组的大小。
43
(2)比较两个字符串的大小,如果相等输出equal,如果不相等输出unequal.
① #include <stdio.h>
② void main()
{
③
④
⑤
⑥
}
错误语句的行号:①、④、⑤
改正后的语句全行:
①、#include <string.h>
④、gets(s1),gets(s2);
⑤、if(strcmp(s1,s2)==0) printf(“equal”);
错误分析:
1、 因为判断两个字符串是否相等不能直接用关系式表示,要用到字符串函数,因此要调用字符
串库文件;
2、 两个语句之间在同一排时用逗号隔开;
3、 判断是字符串是否相等用strcmp函数,当返回值是0时就相等,否则不等。
4. 编写程序
(1)将一个字符串首尾倒置,重新存放。
程序清单:
#include <stdio.h>
void main()
{
char str[20];
int i,t, n;
gets(str);
printf("the old string is :");
puts(str);
printf("\n");
n=strlen(str);
for(i=0;i<n/2;i++)
{
t=str[i];
str[i]=str[n-1-i];
str[n-1-i]=t;
}
printf("the nwe string is:") ;
puts(str); char s1[10],s2[10]; gets(s1);get2(s2); if(s1=s2) printf(“equal”); else printf(“unequal”);
44
getch();
}
程序编写注意事项:
1、 用gets读取从键盘输入的数到数组中,用puts显示数组中所储存的字符串;
2、 在进行元素中的单个字符调换时,用srtlen函数读取字符串的长度,用for循环实现每
一个元素的调换,需要注意的是因为元素下标是从0开始,因此第一个元素对应的需要逆转的元素下标应该为n-1-i,以此类推。
(2)(飞机定票系统)一家小型航空公司刚刚购买了计算机,用于新的自动化定票系统。总裁要求您为新系统编制程序。需要分配该航空公司的唯一一架飞机每个航班的座位(容量:10个座位)。
程序应该轮流显示下列菜单:
Please type 1 for “first class”
Please type 2 for “economy”
如果输入1, 则程序应该分配头等舱内的座位(座位1 ~ 5)。如果输入2 ,则程序应该分配经济舱的座位(座位 6 ~ 10)。然后,程序输出登机证,说明座位号,以及它位于飞机的头等舱,还是经济舱内。
使用一个数组来代表飞机的座位安排。将数组的所有元素初始化为0,以说明所有座位都是空的。当分配每个座位时,将数组的对应元素设置为1,以说明不能再次使用那个座位号。当然,程序不应该分配已经分配过的座位。当头等舱满员时,程序应询问是否可以安排在经济舱内(等等)。如果可以,则进行适当的座位分配。如果不可以,则输出信息“Next Flight leaves in 3 hours”. 程序清单:
#include <stdio.h>
void input();
void print();
void assign();
int seat[11] = {0},i,ch;
char clas[10];
main()
{
input();
while(ch != 'Q')
{
assign();
print();
input();
}
getch();
}
void input()
{
printf("Please type 1 for 'first class'\nPlease type 2 for 'economy'\n"); printf("Please type Q to exit\n");
45
scanf("%d",&ch);
}
void assign()
{
if(ch==1)
i=1;
else
i=6;
while(seat[i] && i<10)
i++;
if(i<=5)
{
strcpy(clas,"First");
seat[i] = 1;
}
else
{
strcpy(clas,"Economy");
seat[i] = 1;
}
if(ch == 1 && i<=5)
return;
else if(ch == 2 && i<10)
return;
else
{
printf("The %s is full,do you want a another class seat?1 for yes/2 for no\n",clas);
scanf("%d",&ch);
if(ch == 1)
input();
else
{
printf("Next Flight leaves in 3 hours\n\n");
input();
}
}
}
void print()
{
printf("Your seat number is %d located in %s\n\n\n",i,clas);
}
46
程序编写注意事项:
(3)(输出数组)编写一个递归函数printArray,它以数组和数组大小作为参数,并且不返回任何值。当数组大小为0时,函数应该停止处理并返回。
#include <stdio.h>
void printArray(int *ptr,int n)
{
if(n == 0)
return;
printf("%d ",*(ptr + n - 1));
printArray(ptr,n-1);
}
void main()
{
int a[10]={1,2,3,5,6,7};
int n=6;
printArray(a,n);
getch();
}
47
实验八 指针
(验证性实验、综合性实验 2学时)
(一)、实验目的
1.掌握指针的概念、会定义和使用指针变量
2.掌握指针与一维数组、二维数组、字符数组的关系
(二)、实验内容
1.写出下列程序的运行结果
(1)#include <stdio.h>
void fun(int * a,int * b)
{
int k;
k=*a;*a=*b;*b=k;
}
void main( )
{
int a=3,b=6;
fun(&a,&b);
printf(“%d,%d”,a,b);
}
运行结果:
6, 3
分析:
1、 此函数是关于函数与指针的应用,fun函数的形参是两个指向int类型的指针变量,整
个函数是实现了将两个指针整型变量调换位置。
2、 在main函数中,将a和b的地址传递给调用函数中,在函数调用时通过指针间接运算
交换了值。
(2)#include <stdio.h>
void fun(int * a,int * b)
{
int *k;
k=a;a=b;b=k;
}
void main( )
{
int a=3,b=6,*x=&a,*y=&b;
fun(x,y);
printf(“%d,%d”,a,b);
}
运行结果:
3,6
分析:
1、 此函数也是关于函数和指针的应用,fun函数的形参变量也是int类型的指针变量,用 48
来接收地址,k定义成整型的指针变量,fun函数的作用是通过间接指针运算实现两个值交换位置。
2、 在main函数中,x和y定义成为指向整形变量的指针,并分别初始化a 和b的地址,
在调用fun函数时作为实参传递给fun函数进行间接指针运算。
3、 但是因为是将a和b的地址付给x和y,在进行运算后是x和y所指向的地址发生变化,
而a和b本身的值没变,输出a和b的值,所以结果为3和6.
(3)#include <stdio.h>
void main( )
{
int a[ ]={1,2,3,4,5,6,7,8,9,0},*p;
p=a;
printf(“\n%d”,*p+9);
}
运行结果:
10
分析:
1、 定义了一个大小为10的整型数组,并且初始化值,定义了一个指向整型数据的指针变量
p;
2、 将数组a的首地址赋给了指针变量p,因为p指向的值是1,所以*p+9=10,输出结果为
10.
(4)#include <stdio.h>
fun(int *s,int n1,int n2)
{
int i,j,t;
i=n1;j=n2;
while(i<j)
{
t=*(s+i);*(s+i)=*(s+j);*(s+j)=t;
i++;j--;
}
}
void main()
{
int a[10]={1,2,3,4,5,6,7,8,9,0},i,*p=a;
fun(p,0,3);fun(p,4,9);fun(p,0,9);
for(i=0;i<10;i++) printf("%d",*(a+i));
}
运行结果:
5678901234
分析:
1、 此函数是关于函数和数组指针的应用,fun函数的形参是一个整型指针和两个整型变
量,将传递过来的值付给i和j,用while循环实现将指针指向的两个数组元素的值进行调换,直到i<j时停止;
49
2、 在main函数中,定义了一个大小为10的整型数组,并初始化了值,定义了一个整型
的指针,并初始化值为指向数组首地址的指针;
3、 fun(p,0,3)调用后a[1]到a[3]的值应为4,3,2,1;fun(p,4,9) 调用后a[4]到a[9]
的值应为0,9,8,7,6,5;fun(p,0,9) 调用后a[0]到a[9]的值应为5678901234;
4、 在用指针进行数组元素的访问时*(a+i)=a[i];
2.程序填空
(1)下面函数用来求出两个整数之和,并通过形参传回两数相加之和值,填空。 #include <stdio.h>
int add(int x,int y,_②_____z);
void main()
{
int a=3,b=4,c;
add(_____①_________);
printf(“%d\n”,c);
}
int add(int x,int y,_②_____z)
{
_③_____=x+y;
}
填空①:(a,b,&c)
填空②:int *z
填空③:*z
程序分析:
1. 此程序是关于函数与指针的应用。将指针作为函数的参数,在add函数中定
义两个整型变量和一个整型指针,指针用来接收传递过来用于储存两数之和
的变量;
2. 在mian函数中将要计算的变量传给调用函数,并将c的地址传递过去,所以
在调用函数运行时,通过间接指针运算就将和保存在c里面了。
(2)下面的程序通过函数average计算数组中各元素的平均值,请填空。
#include <stdio.h>
float average(int *pa,int n)
{ int i;
float avg=0.0;
for(i=0;i<n;i++)
avg=avg+_??______;
avg=__??_____;
return avg;
}
void main()
{
int i,a[5]={2,4,6,8,10};
50
float m;
m=average(a,5);
printf("m=%f\n",m);
}
填空①:avg=avg + *(p+i);
填空②:avg/n;
程序分析:
1、 此程序是关于指针与函数及数组的应用,在自定义函数的参数中,声明了一个整型指
针和一个整型变量,指针用来接收传递过来的数组,变量用来接收一个控制循环的计数器,函数有返回一个float类型的值;
2、 在mian函数调用将数组名和一个数传递过去,指针变量里存储的是数组的首地址,
用循环进行数组元素的累加,因为指针变量里装的是首地址,因此要用(p+i)表示数组元素的移动,用累加的最后值除以个数就是平均数,并将值返回赋给m。
3.程序改错
写出有错误语句的行号,及改正后的语句全行。(每行语句前的序号只标注行号,非程序本身的内容)
(1)将两个整数值进行交换。
① #include <stdio.h>
② swap(int *p,*q);
{
③
④
⑤
⑥
⑦
}
⑧ void main()
{
int a =10,b=20;
swap(&a,&b);
printf(“%d%d\n”,a,b); ⑨ ⑩ ⑾
}
错误语句的行号:②
改正后的语句全行:swap(int *p, int *q)
错误分析:
(1)、此程序是关于函数与指针的应用,当用指针作为函数的形参时,在定义和声明的时候每一个指针要有相应的类型,因为在c语言中,每个变量都必须声明为某种类型;
(2)、自定义函数定义时后面不加分号。
(2)写出程序运行结果:
① #include ″stdio.h″
② main()
{ int *t,a; t=&a; *t = *p; *p = *q; *q = *t;
51
③
④
⑤
⑥
⑦
} int a[]={1,2,3,4,5,6,7,8,9,10,11,12}; int *p=a+5; int *q=null; q=p+5; printf(“%d %d”,*p,*q);
错误语句的行号:⑤
改正后的语句全行:int *q=NULL;
错误分析:
在c语言中,可以在定义指针变量时带有一个初始值NULL或零,但NULL必须是大写的。
4、编程题(选做题)
利用函数把字符数组b,连接到字符数组a的后面,并返回字符数组a中新的长度。 程序清单:
#include <stdio.h>
char stracts(char *p, char *q);
int strlens(char *ptr,char s1[]);
void main()
{
char a[20],b[20];
int n;
printf("Input :");
gets(a);
printf("Input anther :");
gets(b);
stracts(a,b);
printf("The new sting is %s:", a);
n=strlens(a,a);
printf("\nThe new length is %d:",n);
getch();
}
char stracts(char *p,char *q)
{
while(*p != '\0')
{
p++;
}
while(*q !='\0')
{
*(p++)=*(q++);
}
*p++='\0' ;
}
int strlens(char *ptr,char s1[])
{
52
int n;
while(*ptr != '\0')
{
ptr++;
}
n=ptr-s1;
return(n);
}
编程注意事项:
运用函数与指针编写此程序,注意在定义指针时类型不搞错,传递字符串时要正确传递,在将第二个字符串赋给第一个字符串结束后要人工给最后一个元素赋空值,否则将导致程序的不可显示。
53
实验九 结构体、共用体和文件
(验证性实验、设计性实验 2学时)
(一)、实验目的:
1.掌握结构体类型和共用体类型变量
2.结构体类型数组和结构体类型指针的定义
3.掌握链表的定义及操作
4.掌握文件的打开、关闭和文件的读写操作
(二)、实验内容
1.写出程序的运行结果
(1)以下程序的输出结果是:
#include <stdio.h>
union
{
int num;
struct
{char c1,c2;} sc;
}un;
void main()
{
un.sc.cl=65;un.sc.c2=97; un.num=0;
printf("%d\n",un.sc.c2);
}
运行结果:
结果分析:
因为共用体与结构体不同,在共用体中,所有成员使用相同的存储空间,就是说每次处理一个成员,在此程序中,最后处理的是un.num=0,所以结果为0。
(2)以下程序的输出结果是:
#include <stdio.h>
typedef union
{
long i;
int k[5];
char c;
}DATE;
struct date
{
int cat;
DATE cow;
double dog;
}too;
DATE max:
void main()
54
{
printf(″%d\n″,sizeof(struct date)+sizeof(max));
}
运行结果:
30;
结果分析:
一元运算符sieof可以获知结构体或其他任意变量的大小,在结构体DATE中,long int类型占4个字节,int类型的数组大小为5,char类型长度为1,所以总字节为10;结构体date中,因为嵌套了一个大小为10的DATE,int和double总长为10,所以总共大小为30。
2.填空题
(1)下面程序建立一个单向链表。
#include <stdio.h>
void main()
{
struct stud
{
long num;
float score;
struct stud _______;
}stud1,stud2,stud3,*head;
stud1.num = 1;stud1.score = 89.5;
stud2.num = 2;stud2.score = 90.5;
stud3.num = 3;stud3.score = 94.5;
head = &stud1;
stud1.next = &stud2;
stud2.next = &stud3;
stud3.next = NULL;
}
填空:*next
运行分析:这是一个指向相同结构类型的兹引用结构体,可以用head访问 stud1,用stud1的next访问stud2,stud2的next来访问stud3,而stud3的next指向一个空指针。
(2)以下程序把a数组中的数据输出到fp所指的二进制文件中。
#include <stdio.h>
#define N 10
void main()
{
float a[N];
int i;
FILE *fp;
for(i=0;i<N;i++)
scanf(“%f”,a+i);
fp=fopen(“file.dat”,“wb”);
55
fwrite(a,4*N,1,fp);
______________________;
}
填空:
fclose(fp);
运行分析:
1、 FILE *fp是把fp声明为指向file类型文件的指针;
2、 fp=fopen(“file.dat”,“wb”)是指把文件名为file.dat的文件以只写的方式
打开;
3、 fwrite(a,4*N,1,fp)将a数组中的前4个元素都写到打开的文件中
4、 文件打开后必须用fclose()命令关闭。
(3)下面程序把一个名为f1.doc的文件拷贝到一个名为f2.doc的文件中,请在__处添入适当命令行,使之正确运行。
#include <stdio.h>
void main( )
{
char c;
FILE *fp1, *fp2;
fp1=fopen(“f1.doc”,“r”); fp2=
c=fgetc(fp1);
while(c!=EOF)
{
fputc(c,fp2);
c=fgetc(fp1);
}
fclose(fp1);
fclose(fp2);
}
填空;
Fp2=fopen(“f2.doc”,“w”)
运行分析:
将f1.doc以只读方式打开,f2.doc以只写方式打开,用while循环,直到f1的文件尾结束,用fgetc()从f1中读取文本,用fputc()写入到f2中,最后关闭两个打开的文件。
3.改错题
(1)定义一个结构体变量a,输出a变量中每一个成员的值。
① #include <stdio.h>
② void main()
{
struct
{
char flag; float t; ④ ⑤
⑥ ③ } STC;
56
⑦
⑧
⑨ } STC a={‘a’,46}; printf(“%c,%f\n”,a.flag,a.t);
错误语句的行号:③、⑥、⑦
改正后的语句全行:
③、struct stc;
错误分析:
1、 结构体的定义时要将结构体类型名写在大括号前,定义结束后用分号结尾;
2、 给结构体变量初始化值时要将类型名变量名都写上。
(2)从键盘输入一些字符,逐个把它们送到磁盘上去,直到输入一个“#”号为止。 ① #include <stdio.h>
② void main()
{
③ file *fp;
④ char ch,filename[10];
⑤ scanf(“%s”,filename);
⑥ if((fp=fopen(filename,”w”))==NULL)
⑦ { printf(“cannot open file\n”);
exit(0);
ch = getchar();
while(ch!=’#’)
{
} fputc(ch,fp); putchar(ch); ch=getchar(); ⑥、} ; ⑦、struct stc a={‘a’,46}; ⑧ ⑨ } ⑩ ⑾ ⑿ ⒀ ⒁ ⒂
} ⒃ fclose(fp);
错误语句的行号:
③
改正后的语句全行:
FILP *fp
错误分析:给指向文件类型的指针定义时FILP必须要大写。
57
4.编程题(选做)
(1)有10名学生,每名学生有语文、数学、外语三门课程的成绩,计算每名学生的总成绩,然后按总成绩由高到低排序,若总成绩相同,再按外语成绩由高到低排序。
要求:① 利用结构体数组存放数据。
② 通过函数调用方式。
程序清单:
编写程序注意事项:
(2)编写一个程序,它使用sizeof运算符来确定计算机系统上不同数据类型的字节数。将结果写入到文件“datasize.dat”中,这样您可以稍后输出结果。文件中的结果格式如下:
58
程序清单:
编写程序注意事项:
59
实验十 C程序综合性实验
(综合性实验、设计性实验 4学时)
(一)、目的要求:
1.巩固三种不同循环语句,实现循环程序设计。
2.巩固C语言函数定义及调用规则。
3.掌握结构体类型的概念及定义方法;结构体变量的定义和引用。
4.掌握文件的读写、定义、输入输出。
(二)、实验内容:(可以任选其一)
1.将5名学生的数据从键盘输入,然后送入磁盘文件student1.c中保存,最后从磁盘调入这些数据,依次打印出来(用fread和fwrite函数)。设学生数据包括:学号、姓名、成绩。
2.对存放在student1.c中的各学生数据按成绩高低顺序排序,将排好序的各记录存放在student2.c文件中,并打印出student2.c文件中所有学生记录。
3.在student1.c的基础上,增加一个新学生的数据,要求按成绩高低顺序插入到原有文件中,然后存放到student3.c中,并打印出student3.c中顺序号为奇数的学生记录(即第1、3、5学生的数据)。
4.在student1.c的基础上,删除一个学生的数据,然后存放到student4.c中,并打印出student4.c中顺序号为偶数的学生记录(即第2、4学生的数据)。
程序清单:
60
编写程序注意事项:
61