C语言上机指导
指导教师:李辉 李晓丽
东北电力大学电气工程学院
2006年3月
实验2 数据类型、运算符和表达式
1. 实验目的
掌握C语言数据类型,熟悉如何定义一个整形、字符型和实型的变量,以及对他们赋值的方法。
掌握不同的类型数据之间赋值的规律。
学会使用C的有关算术运算符,以及包含这些运算符的表达式,特别是自加(++)和自减(--)运算符的使用。
进一步熟悉C程序的编辑、编译、连接和运行的过程。
2. 实验内容和步骤
输入并运行下面的程序
#include <stdio.h>
void main()
{
char c1,c2;
c1 = 'a';
c2 = ‘b’;
printf (“%c %c\n”,c1,c2);
}
(1). 运行此程序。
(2).在此基础上增加一个语句:
printf(“%d%d\n”,c1,c2);
再运行,并分析结果。
(3). 再将第2行改为:
int c1,c2;
再使之运行,并观察结果。
(4).再将第 3、4行改为:
c1 = a; /* 不用单撇号 */
c2 = b;
再使之运行,分析其运行结果。
(5).再将第 3、4行改为:
c1 =,a”; /* 用双撇号 */
c2 =,b”;
再使之运行,分析其运行结果。
(6).再将第 3、4行改为:
c1 = 300; /* 用大于255的整数 */
c2 = 400;
再使之运行,分析其运行结果。
输入并运行教材第3章习题3.6给出的程序
#include <stdio.h>
void main()
{
char c1 = ‘a’,c2 = ‘b’,c3 = ‘c’,c4 = ‘\101’,c5 = ‘\116’;
printf (“a%c b%c\tc%c\tabc\n”,c1,c2,c3);
printf(“\t\b%c%c”,c4,c5);
}
在上机前先用人工分析程序,写出应得结果,上机后将二者对照。
输入并运行下面的程序
#include <stdio.h>
void main()
{
int a,b;
unsigned c,d;
long e,f;
a = 100;
b = -100;
e = 50000;
f = 32767;
c = a;
d = b;
printf(“%d,%d\n”,a,b);
printf(“%u,%u\n”,a,b);
printf(“%u,%u\n”,c,b);
c = a = e;
d = b = f;
printf(“%d,%d\n”,a,b);
printf(“%u,%u\n”,c,d);
}
请对照程序和运行结果分析:
(1).将一个负整数赋给一个无符号的变量,会得到什麽结果。画出它们在内存中的表示形式。
(2). 将一个大于32765的长整数赋给整形变量,会得到什麽结果。画出它们在内存中的表示形式。
(3).将一个长整数赋给无符号的变量,会得到什麽结果(分别考虑该长整数的值大于或等于65535 以及小于65535 的情况)。画出它们在内存中的表示形式。
同学们可以改变程序中各变量的值,以便比较。例如,a = 65580,b = -40000,e = 65535,f = 65580。
输入习题3.10
#include <stdio.h>
void main()
{
int i,j,m,n;
i = 8;
j = 10;
m = ++i;
n = j++;
printf(“%d,%d,%d,%d”,i,j,m,n);
}
(1).运行程序,注意 i、j、m、n 各变量的值,分别作以下改动并运行。
(2).将第4、5行改为:
m = i++;
n = ++j;
再运行。
(3).将程序改为:
#include <stdio.h>
void main()
{
int i,j;
i = 8;
j = 10;
printf(“%d,%d”,i++,j++);
}
(4).在(3)的基础上,将printf 语句改为:
printf(“%d,%d”,++i,++j);
(5).再将printf 语句改为:
printf(“%d,%d,%d,%d”,i,j,i++,j++);
(6).将程序改为:
#include <stdio.h>
void main()
{
int i,j,m=0,n=0;
i = 8;
j = 10;
m+= i++; n-= --j;
printf(“i=%d,j=%d,m=%d,n=%d”,i,j,m,n);
}
按习题3.7的要求编程序并上机运行该题的要求是:
要将”China”译成密码,译码规律是:用原来字母后面的第4个字母代替原来的字母。例如,字母”A”后面第4个字母是”E”,用”E”代替”A”。因此,”China”应译为”Glmre”。请编一程序,用赋初值的方法使c1、c2、c3、c4、c5 五个变量的值分别为’C’、’h’、’i’、’n’、’a’,经过运算,使c1、c2、c3、c4、c5分别变为’G’、’l’、’m’、’r’、’e’、,并输出。
①输入事先已编好的程序,并运行该程序。分析是否符合要求。
②改变c1、c2、c3、c4、c5、的初值为:’T’、’o’、’d’、’a’、’y’,对译码规律作如下补充:’W’用’A’ 代替,’X’用’B’代替,’Y’用’C’代替,’Z’用’D’代替。修改程序并运行。
③将译码规律修改为:将字母用它前面的第4个字母代替,例如:’E’用’A’ 代替,’Z’用’U’代替,’D’用’Z’代替,’C’用’Y’代替,’B’用’X’代替,’A’用’V’代替。修改程序并运行。
实验 3 最简单的C 程序设计
1. 实验目的
掌握C语言中使用最多的一种语句——赋值语句的使用方法。
掌握各种类型数据的输入输出的方法,能正确使用各种格式转换符。
2. 实验内容和步骤
掌握各种格式转换符的正确使用方法
(1).输入程序
#include <stdio.h>
void main()
{
int a,b;
float d,e;
char c1,c2;
double f,g;
long m,n;
unsigned int p,q;
a = 61; b = 62;
c1 = ’a’; c2 = ’b’;
d = 3.56; e = -6.87;
f = 3157.890121; g = 0.123456789;
m = 50000; n = -60000;
p = 32768; q = 40000;
printf(“a=%d,b=%d\nc1=%c,c2=%c\nd=%6.2f,e=%6.2f\n”,a,b,c1,c2,d,e);
printf(“f=%15.6f,g=%15.12f\nm=%ld,n=%ld\np=%u,q=%u\n”,f,g,m,n,p,q);
}
(2).运行此程序并分析结果。
(3). 在此基础上,修改程序的第8-13行:
a = 61; b = 62;
c1 = ’a’; c2 = ’b’;
f = 3157.890121; g = 0.123456789;
d = f; e = g;
p = a = m = 50000; q = b = n = -60000;
运行程序,分析结果。
(4). 改用scanf 函数输入数据而不用赋值语句,scanf 函数如下:
scanf(“%d,%d,%c,%c,%f,%f,%lf,%lf,%ld,%ld,%u,%u”,&a,&b,&c1,&c2,&d,&e,&f,&g,&m,&n,&p,&q);
输入的数据如下:
61,62,a,b,3.56,-6.87,3157,890121,0.123456789,50000,-60000,37678,40000↙
(说明:lf和ld格式符分别用于输入double型和long型数据)分析运行结果。
(5).在(4) 的基础上将printf语句改为:
printf(“a=%d,b=%d\nc1=%c,c2=%c\nd=%15.6f,e=%15.12f\n”,a,b,c1,c2,d,e);
printf(“f=%f,g=%f\nm=%d,n=%d\np=%d,q=%d\n”,f,g,m,n,p,q);
运行程序。
(6).将p、q改用%o格式符输出。
(7).将scanf函数中的%lf和%ld改为%f和%d,运行程序并观察分析结果。
按习题4.8要求编写程序题目为:
设圆半径r=1.5,圆柱高h=3,求圆周长、圆面积、圆球表面积、圆球体积、圆柱体积。用scanf 输入数据,输入计算结果。输出时要有文字说明,取小数点后两位数字。
编程序,用getchar 函数读入两个字符给c1、c2,然后分别用putchar函数和printf函数输出这两个字符。
上机运行程序,比较用printf和putchar 函数输出字符的特点。
实验4 逻辑结构程序设计
1. 实验目的
了解C语言表示逻辑量的方法(以0代表“假”,以非0代表“真” )。
学会正确使用逻辑运算符和逻辑表达式。
熟练掌握if语句和switch语句。
结合程序掌握一些简单的算法。
学习调试程序。
2. 实验内容本实验要求事先编好解决下面问题的程序,然后上机输入程序并调试运行程序。
(1).有一函数:
用scanf函数输入x的值,求y值。(习题5.5)
运行程序,输入x的值(分别为x<1、1≤x<10、x≥10三种情况),检查输出的y值是否正确。
(2).给出一个百分制成绩,要求输出成绩等级A、B、C、D、E。90分以上为A,81-89分为B,70-79分为C,60-69分为D,60分以下为E。(习题5.6)。
① 事先编好程序,要求分别用if语句和switch语句实现。运行程序,并检查结果是否正确。
② 再运行一次程序,输入分数为负值(如-70),这显然是输入时出错,不应给出等级。修改程序,使之能正确处理任何数据。当输入数据大于100或小于0时,通知用户“输入数据错”,程序结束。
(3).给一个不多于5位的正整数,要求:①求出它是几位数;②分别打印出每一位数字;③按逆序打印出各位数字,例如原数为321,应输出123。(习题5.7)
应准备以下测试数据:
要处理的数为1位正整数;
要处理的数为2位正整数;
要处理的数为3位正整数;
要处理的数为4位正整数;
要处理的数为5位正整数。
除此之外,程序还应当对不合法的输入作必要的处理。例如:
输入负数;
输入的数超过5位(如123 456)。
(4).输入4个整数,要求按由小到大顺序输出。
得到正确结果后,修改程序使之按由大到小顺序输出。(习题5.9)
(5).计算DNA分子中A、G、C、T四种碱基的分子量。
(6).根据输入的三角形的三边判断是否能组成三角形,若可以则输出它的面积和三角形的类型。
(7).现有十二个小球,其中一个球的重量与其它十一个的重量不相同,但不知道是轻还是重。试用天平称三次,把这个非标准球找出来,并指出它比标准球是轻还是重。
要求:
(1).用嵌套的选择结构编写程序;
(2). 调试程序时,必须把十二个球或轻或重共24种可能性都找出来。
实验5 循环控制
1. 实验目的熟悉掌握用while语句,do-while语句和for语句实现循环的方法。掌握在程序设计中用循环的方法实现一些常用算法(如穷举、迭代、递推等)。进一步学习调试程序。
2. 实验内容编程序并上机调试运行。
(1). 输入两个正整数m和n,求它们的最大公约数和最小公倍数。(习题6.1)
在运行时,输入的值m>n,观察结果是否正确。
再输入时,使m<n,观察结果是否正确。
修改程序,不论m和n为何值(包括负整数),都能得到正确结果。
(2). 输入一行字符,分别统计出其中的英文字母、空格、数字和其它字符的个数。(习题6.2)
在得到正确结果后,请修改程序使之能分别统计大小写字母、空格、数字和其它字符的个数。
(3). 用牛顿迭代法求方程2x3-4x2+3x-6=0在1.5附近的根。(习题6.12)
在得到正确结果后,请修改程序使所设的x初值由1.5改变为100、1000、10000,再运行,观察结果,分析不同的x初值对结果有没有影响,为什么?
修改程序,使之能输出迭代的次数和每次迭代的结果,分析不同的x初始值对迭代的次数有无影响。
(4). 猴子吃桃问题。猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个。第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,见只剩一个桃子了。求第一天共摘了多少桃子。(习题6.10)
在得到正确结果后,修改题目,改为猴子每天吃了前一天剩下的一半后,再吃两个。请修改程序,并运行,检查结果是否正确。
实验6 数组
1. 实验目的
掌握一维数组和二维数组的定义、赋值和输入输出的方法;
掌握字符数组和字符串函数的使用;
掌握与数组有关的算法(特别是排序算法)。
2. 实验内容编程序并上机调试运行。
(1).用选择法对10个整数排序。10个整数用scanf函数输入。(习题7.2)
(2).有15个数存放在一个数组中,输入一个数,要求用折半查找法找出该数是数组中第几个元素的值。如果该数不在数组中,则输出“无此数”。以15个数用赋初值的方法在程序中给出。要找的数用scanf函数输入。(习题7.9)
(3).将两个字符串连接起来,不要用strcat函数。
(4).找出一个二维数组的“鞍点”,即该位置上的元素在该行上最大,在该列上最小。也可能没有鞍点。(习题7.8)
应当至少准备两组测试数据:
①二维数组有鞍点
9 80 205 40
90 -60 96 1
210 -3 101 89
②二维数组没有鞍点
9 80 205 40
90 -60 196 1
210 -3 101 89
45 54 156 7
用scanf函数从键盘输入数组各元素的值,检查结果是否正确。题目并未指定二维数组的行数和列数,程序应能处理任意行数和列数的数组。因此,从理论上来说,应当准备许多种不同行数和列数的数组数据,但这样的工作量太大,一般来说不需要这样做,只需准备典型的数据即可。
如果已指定了数组的行数和列数,可以在程序中对数组元素赋初值,而不必用scanf函数。请同学们修改程序以实现之。
实验7 函数
1. 实验目的
掌握定义函数的方法;
掌握函数实参与形参的对应关系以及“值传递”的方式;
掌握函数的嵌套调用和递归调用的方法;
掌握全局变量和局部变量动态变量、静态变量的概念和使用方法。
学习对多文件程序的编译和运行。
2. 实验内容编程序并上机调试运行。
(1).写一个判别素数的函数,在主函数输入一个整数,输出是否素数的信息。(习题8.3)
本程序应当准备以下测试数据:17、34、2,1、0。分别输入数据,运行程序并检查结果是否正确。
(2).用一个函数来实现将一行字符串中最长的单词输出。此行字符串从主函数传递给该函数.(习题8.10)
把两个函数放在同一个程序文件中,作为一个文件进行编译和运行。
把两个函数分别放在两个程序文件中,作为两个文件进行编译、连接和运行。
(3).用递归法将一个整数n转换成字符串。例如,输入483,应输出字符串“483”。n的位数不确定,可以是任意的整数。(习题8.17)
(4).求两个整数的最大公约数和最小公倍数。用一个函数求最大公约数,用另一函数根据求出的最大公约数求最小公倍数。(习题8.1)
①不用全局变量,分别用两个函数求最大公约数和最小公倍数。两个整数在主函数中输人,并传送给函数l,求出的最大公约数返回主函数,然后再与两个整数一起作为实参传递给函数2,以求出最小公倍数,再返回到主函数输出最大公约数和最小公倍数。
②用全局变量的方法,分别用两个函数求最大公约数和最小公倍数,但其值不由函数带回。将最大公约数和最小公倍数都设为全局变量,在主函数中输出它们的值。
(5). 写一函数,输入一个十六进制数,输出相应的十进制数。(习题8.16)
实验8 编译预处理
1. 实验目的
掌握宏定义的方法;
掌握文件包含处理方法;
掌握条件编译的方法。
2. 实验内容
编程序并上机调试运行。
(1).定义一个带参数的宏,使两个参数的值互换。在主函数中输入两个数作为使用宏的实参,输出已交换后的两个值。(习题9.1)
(2).设计输出实数的格式,包括:①一行输出一个实数;②一行内输出两个实数;③一行内输出三个实数。实数用“% 6.2f”格式输出。(习题9.6)
用一个文件Print-format.h包含以上用#define命令定义的格式。在自己的文件(自己命名)中用#include命令将print-format.h文件包含进来。在程序中用scanf函数读入三个实数给f1、f2、f3。然后用上面定义的三种格式分别输出:①f1;②f1、f2;③f1、f2、f3。
(3). 用条件编译方法实现以下功能:
输入一行电报文字,可以任选两种输出,一为原文输出;一为将字母变成其下一字母(如'a'变成'b'……'z'变成'a'。其他字符不变)。用#define命令来控制是否要译成密码。例如:
若#define CHANGE 1则输出密码。若#define CHANGE 0则不译成密码,按原码输出。(习题 9.10)
编写程序,用条件编译方法来实现题目要求。
首先在程序中用“#define CHANGE 1”,运行程序,应得到密码。
将“#define CHANGEl”改为“#define CHANGE 0”,再运行程序,应得到原文。
实验9 指针
1. 实验目的
通过实验进一步掌握指针的概念,会定义和使用指针变量;
能正确使用数组的指针和指向数组的指针变量;
能正确使用字符串的指针和指向字符串的指针变量;
能正确使用指向函数的指针变量;
了解指向指针的指针的概念及其使用方法。
2. 实验内容
编程序并上机调试运行程序(都要求用指针处理)。
(1).输入三个整数,按由小到大的顺序输出,然后将程序改为:输入三个字符串,按由小到大顺序输出。(习题l0.1、10.2)
(2).将一个3X3的矩阵转置,用一函数实现之。(习题10.9)
在主函数中用scanf函数输入以下矩阵元素:
l 3 5
7 9 11
13 15 19
将数组名作为函数实参,在执行函数的过程中实现矩阵转置,函数调用结束后在主函数中输出已转置的矩阵。
(3).有n个人围成一圈,顺序排号。从第1个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。(习题10.5)
(4).用一个函数实现两个字符串的比较,即自己写一个strcmp函数,函数原型为:int strcmp (char * p1,char * p2);
设p1指向字符串s1,p2指向字符串s2,要求当s1=s2时,函数返回值为 0,如果sl≠s2,则返回它们二者第一个不相同字符的ASCII码差值(如“BOY”与“BAD”的第二个字母不相同,“O”与“A”之差为79—65=14);如果sl>s2,则输出正值;如果sl<s2则输出负值。(习题10.17)
两个字符串s1、s2由main函数输入,strcmp函数的返回值也由main函数输出。
(5). 写一个用矩形法求定积分的通用函数,分别求:
说明:sin、cos、exp已在系统的数学函数库中,程序开头要用#include<math.h>。(习题10.13)
(6). 用指向指针的指针的方法对n个整数排序并输出。要求将排序单独写成一个函数。n和各整数在主函数中输入,最后在主函数中输出。(习题10.21)
实验10 结构体和共用体
1. 实验目的
掌握结构体类型变量的定义和使用;
掌握结构体类型数组的概念和使用;
掌握链表的概念,初步学会对链表进行操作;
掌握共用体的概念与使用。
2. 实验内容
编程序,然后上机调试运行。
(1).有10个学生,每个学生的数据包括学号、姓名、3门课的成绩,从键盘输入10个学生数据,要求打印出3门课总平均成绩,以及最高分的学生的数据(包括学号、姓名、3门课的成绩、平均分数)。(习题11.5)
要求用input函数输入10个学生数据;用average函数求总平均分;用max函数找出最高分的学生数据;总平均分和最高分学生的数据都在主函数中输出。
(2). 13个人围成一圈,从第1个人开始顺序报号1、2、3。凡报到“3”者退出圈子,找出最后留在圈子中的人原来的序号。(习题11.9)本题要求用链表实现。
(3).建立一个链表,每个结点包括:学号、姓名、性别、年龄。输入一个年龄,如果链表中的结点所包含的年龄等于此年龄,则将此结点删去。(习题11.11)
(4).输入和运行以下程序
union data
{int i[2];
float a;
long b;
char c[4];
}u;
main ( )
{scanf("%d,%d",&u.i[0],&u.i[1]);
printf(i[0]=%d,i[1]=%da=%fb=%1dc[0]=%c,c[1]=%c,c[2]=%c,c[3]=%c,
u.i[0],u.i[1],u.a,u.b,u.c[0],u.c[1],u.c[2],u.c[3]);
}
输入两个整数10000、20000给u.i[0]和u.i[l],分析运行结果。
然后将scanf语句改为:
scanf("%ld",&u.b);
输入60000给b,分析运行结果。
实验11 位运算
1.? 实验目的
掌握按位运算的概念和方法,学会使用位运算符;
学会通过位运算实现对某些位的操作。
2. 实验内容
编写程序,上机调试并运行。
(1).编写一程序,检查所用的计算机系统的C编译在执行右移时是按照逻辑右移的原则,还是按照算术右移的原则进行操作。如果是逻辑右移,请编一个函数实现算术右移;如果是算术右移,请编一个函数实现逻辑右移。(习题12.3)
(2). 编一个函数getbits,从一个16位的单元中取出某几位(即该几位保留原值,其余位为0)。函数调用形式为:
getbits(value,n1,n2)
value为该16位数的值,nl为欲取出的起始位,n2为欲取出的结束位。如:
getbits(0101675,5,8)
表示对八进制数101675,取出其从左面起的第5位到第8位。(习题12.1)
要求把这几位数用八进制数打印出来。注意,应当将这几位数右移到最右端,然后用八进制形式输出。
(3).? 设计一个函数,使给出一个数的原码,能得到该数的补码。(习题12.5)
要求用八进制形式输入和输出。
实验12 文件
1. 实验目的
掌握文件以及缓冲文件系统、文件指针的概念;
学会使用文件打开、关闭、读、写等文件操作函数;
学会用缓冲文件系统对文件进行简单的操作。
2. 实验内容
编写程序并上机调试运行。
(1).有5个学生,每个学生有3门课的成绩,从键盘输入以上数据(包括学生号、姓名、3门课成绩),计算出平均成绩,将原有数据和计算出的平均分数存放在磁盘文件stud中。(习题13.6)
设5名学生的学号、姓名和3门课成绩如下:
99101 Wang 89,98,67.5
99103 Li 60,80,90
99106 Fun 75.5,91.5,99
99110 Ling 100,50,62.5
99113 Yuan 58,68,7l
在向文件stud写入数据后,应检查验证stud文件中的内容是否正确。
(2).将上题stud文件中的学生数据,按平均分进行排序处理,将已排序的学生数据存入一个新文件stu_sort中.(习题13.7)
在向文件stu_sort写入数据后,应检查验证stu_sort文件中的内容是否正确。
(3). 对上题已排序的学生成绩文件进行插入处理,插入一个学生的3门课成绩。程序先计算新插入学生的平均成绩,然后将它按成绩高低顺序插入,插入后建立一个新文件。(习题13.8)
要插入的学生数据为:
99108 Xin 90,95,60
在向新文件stu_new写入数据后,应检查验证stu_new文件中的内容是否正确。