putchar(ch2); }
当编译完成后,运行该程序,出现提示时输入a□b?回车?(此处“□”表示空格符),按Alt?F5观察得到的输出结果为a,本意是通过putchar()函数输出ab,但得到的却只有a,问题出在哪里呢?源程序是没有错误的,我们怀疑是字符变量ch1、ch2的赋值有问题,下面就用集成环境中的Debug|Watches来进行调试观察。两次选择该菜单下的Add watch子项分别加入两个要观察的变量ch1和ch2,然后按F8键来单步执行该程序的各条语句,执行到出现输入提示时重复刚才的内容。当运行完“ch2?getchar();”后,在观察窗口watch中可看到ch1的值为?a?,而ch2的值为?□?,也就是说ch2的值被赋为空格字符,这是由于getchar()函数从输入缓冲区中读数,是按字节一个一个依次进行的。对于以上输入,当然第二个getchar()函数读到的是空格符。为了避免出现这种情况,可以在两个赋值语句中间加入一语句“getchar();”,或输入时在字符中间不要加空格符。
(3) 输入并运行例3.2,学习自增自减运算符的使用。
(4) 输入并运行例4.13、4.14和4.15,掌握用scanf()函数输入数据时的正确格式。特别要注意字符数据与数值数据的混合输入问题。
(5) 以下程序是求三角形周长及面积的程序,试输入并运行。 #include ?stdio.h? #include ?math.h? void main() {
float a, b, c; /* 定义三角形的三边 */ float len, s, area;
scanf(??f?f?f?, &a, &b, &c); /* 输入能够成三角形三边的三个数 */ len?a?b?c; s?len/2;
area?sqrt(s*(s?a)*(s?b)*(s?c)); printf(?l??.2f, area??.2f\\n?, len, area); }
(6) 参照以上程序,编写已知球半径,求球表面积和体积的程序。
实验四 分支及多分支程序设计
1.目的及要求
(1) 掌握关系表达式、逻辑表达式运算结果的表示方法。 (2) 掌握if语句、switch语句的使用方法。 (3) 掌握if语句、switch语句的嵌套使用方法。 2.实验内容
(1) 下面程序用来求x的符号,sign为1,0,?1分别表示正号,无符号,负号。 #include ?stdio.h? void main() {
int x, sign;
printf(?\\n输入x的值: ?);
? 302 ?
scanf(??d?, &x); if (x?0) sign?1; else if (x?0) sign?0; else sign??1;
printf(?sign??d\\n?, sign); }
输入后编译成功运行三遍,分别输入8、?5、0,得到的输出结果分别为1、?1、?1。当输入x的值为零时,得到的结果为?1,这是不正确的,说明程序中有逻辑错误。我们用F8来跟踪该程序的执行,输入为零时,发现程序跳过了语句“sign?0;”而来到“sign??1;”上,显然是“else if”中的条件判断不成立,通过检查发现,这是由于条件运算符“??”写成了赋值运算符“?”。改正后再运行,结果正确。
(2) 输入并运行例4.16,并仿照编写求三角形面积的程序,要求三边长从键盘输入,判断它们能否构成三角形,如能则求面积,否则输出“不能够形成三角形”的信息。
(3) 输入并运行例4.17、4.18和4.19。
(4) 编写习题4.5的(1)、(2)和(3)小题的程序,并上机调试。
实验五 循环程序设计
1.目的及要求
(1) 掌握C语言中用while、do-while、for等控制语句来构成循环的方法。 (2) 学习常用的程序调试方法。
(3) 掌握循环中常用算法如迭代、递推等。 2.实验内容
(1) 编写求1?3?5???99的程序,要求分别用while、do-while、for来做。 (2) 下面的程序用来输出如下图形:
* * * * * * * * * *
#include ?stdio.h?
void main() {
int i, j;
for (i?1; i??4; i??) {
for (j?1; j??i; j??)
printf(?* ?); printf(?\\n?); } }
试在此程序的基础上进行修改、调试,使得它能输出图形: $ $ $
? 303 ?
$ $ $ $ $ $ $
提示:在处理每一行时,应先输出一些空格。
(3) 设计循环程序,输出Fibonacci数列的前12个元素,其输出形式及不完整的程序如下:
x1?1 x2?1 x3?2 x4?3 x5?5 x6?8 x7?13 x8?21 x9?34 x10?55 x11?89 x12?144
#include ?stdio.h? void main() {
int a?1, b?1, i;
for (_________________) {
printf(?x??2d???5dx??2d???5d?, 2*i?1, a, 2*i, b); if (__________) printf(?\\n?); a?a?b; b?b?a; } }
请在for后和if后的括号内填入正确的表达式,并调试通过该程序。 (4) 输入并调试例4.27、4.28和4.29。
(5) 编程用辗转相除法求两个正整数的最大公约数和最小公倍数。
辗转相除法的思想是:设两个正整数m、n,求m/n的余数p,若p?0则n为最大公约数,若p≠0,则把原来的分母作为新的分子,余数p作为新的分母,继续运算??直到余数p?0,则此次运算的分母就是最大公约数。将m*n的结果除以最大公约数就可得到最小公倍数。
(6) 编程用牛顿迭代法求2x3?4x2?3x?6?0在1.5附近的根。要求误差小于1e-5。该方法又称牛顿切线法,其思想是:先任意假定一个与真实的根接近的值xk求出f(xk),再过(xk,f(xk))点作f(x)的切线,交x轴于xk?1,它作为第二次近似根;再由xk?1求出f(xk?1),再过(xk?1,f(xk?1))点作f(x)的切线,交x轴于xk?2,再求出f(xk?2),再作切线??如此进行下去,直到足够接近真正的根为止。下面是用N?S图表示的算法:
输入x(如输入1.5) x0?x f?((2*x?4)*x?3)*x?6 f1?(6x?8)*x?3 求下一个根x?x0?f/f1 当fabs(x?x0)??1e?5 输出x 实验六 函 数
1.目的及要求
(1) 掌握函数的定义和调用方法。
? 304 ?
(2) 掌握函数实参和形参间的值传递关系。 (3) 掌握函数的嵌套调用和递归调用。
(4) 掌握局部变量、全局变量的使用及变量的存储类型。 2.实验内容
(1)下面的程序中主函数调用max()函数来比较两个浮点数的大小,输入并运行它。 #include ?stdio.h?
float max(float x, float y) {
return (x?y?x:y); }
void main() {
float a, b, c;
printf(?\\n输入两个数: ?); scanf(??f?f?, &a, &b); c?max(a, b);
printf(?max is ?.2f\\n?, c); }
如你已经正确运行了它,试完成以下操作:
① 用F8键单步执行该程序,观察亮条的移动;用F7键来跟踪该程序的每一步执行, 观察现象,比较这两者的不同,大家会发现用F7亮条会进入到max()函数体内去跟踪执行,而F8则不会。
② 将max()函数的定义部分移动到main()函数定义的后面,观察编译时有什么错误出现?在main()函数中的printf()函数前加一语句“float max(float, float);”再编译,还有错误没有,为什么会这样?
③ 用F8单步将程序执行到“c?max(a, b);”语句,选择Debug|Evaluate菜单,系统将弹出一个对话框,在Evaluate中输入a回车,则Result框中会显示变量a的值,同样输入b则有b的值显示出来,但输入变量x(或y)时显示的则是“undefined symbol ?x?”这样的信息。改按F7键跟踪执行到return语句,再用刚才的方法来观察a、b、x、y这四个变量的值,则与先前恰恰相反,这说明了各函数中定义的自动变量对其他函数来说是不可见的,并且x、y分别取得了a、b的值(参数的值传递)。
(2) 下面是求x!的递归程序 #include ?stdio.h? fac(int n) {
int f;
if (n!?1) f?n*fac(n?1); else f?1;
return f; }
void main() {
int x?5, y; y?fac(x);
? 305 ?
printf(?x!??d\\n?, y); }
编译成功后,用F7来跟踪递归函数fac()的执行情况,每次进入fac()函数时及每次从该函数返回时,我们用Debug|Evaluate及Debug/Call stack来观察n、f值的变化和进栈出栈情况。
(3) 输入并运行例5.6、5.7、5.8和5.9。
(4) 调试运行习题5.2的(4)小题,并分析运行结果。
实验七 数 组
1.目的及要求
(1) 掌握一维数组和二维数组的定义方法,以及其元素的访问形式。 (2) 掌握用字符数组来处理字符串及字符串处理函数。 (3) 掌握数组处理中的有关排序和查找算法。 2.实验内容
(1) 下面的程序实现对二维数组元素进行赋值并输出,请上机调试运行。 #include ?stdio.h? #define ROW 5 #define COL 5 void main() {
int i, j;
int a[ROW][COL]; for (i?0; i?ROW; i??) {
for (j?0; j?COL; j??) {
a[i][j]?i*ROW?j; printf(??5d?, a[i][j]); }
printf(?\\n?); } }
该程序的正确输出结果为: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
试对该程序进行修改,使其输出结果为:
0 1 2 3 4 sum1?10 sum?10 5 6 7 8 9 sum2?35 sum?45 10 11 12 13 14 sum3?60 sum?105 15 16 17 18 19 sum4?85 sum?190
? 306 ?