(1)掌握正确的函数定义与调用,需要时会正确使用函数声明。会正确设置形式参数,理解参数传递及程序的执行流程。
(2)理解各种不同存储类别变量的生命期与作用域
(3)进一步熟悉调试器的使用,会利用调试器进行查错改错,会跟踪程序运行的每一步,观察变量的变化情况。
硬件: 微型计算机
软件: Windows 操作系统、Microsoft Visual Studio 2010
编程序exp4_2.c,巧用函数调用,打印不同行数和字符构成的等腰三角形。具体要求:定义一个函数原型void DrawTriangle (int n,char c); ,实现功能为打印一个n行的由字符c组成的等腰三角形。主程序调用该函数,实现打印5行“ '* ’ ”、10行“ '# ’ ”的等腰三角形。
实验解答:
#include
void DrawTriangle(int n, char c)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j <= n - i; j++)
{
printf(" ");
}
for (int j = 0; j <= 2 * i; j++)
{
printf("%c", c);
}
printf("\n");
}
printf("\n\n");
}
int main()
{
int n = 0;
char c = '0';
DrawTriangle(5, '*');
DrawTriangle(10, '#');
return 0;
}
当值为81时,屏幕无法正常显示’*’。因为屏幕缓冲区的宽度为160和窗口宽度为158。
把屏幕缓冲区的宽度调整为162(或更大)后,刚才的实参提供后仍然能正常显示。
编程序exp4_5.c,验证歌德巴赫猜想:2000以内的正偶数(不包括2)都能够分解为两个质数之和。(算法提示:将整数分解为两个整数,然后判断它们是否均为质数。若是,则满足题意并输出;否则重新进行分解和判断。其中,判断一个整数是否为质数采用函数实现。每个偶数只要得到一种分解就停止,不必要求出该偶数的所有质数和组合)。
实验解答: 源程序exp4_5.c的代码是:
#include
#include
int judgePrime(int n)
{
int i, k;
int judge = 1;
if (n == 1) { judge = 0; }
k = (int)sqrt((double)n);
for (i = 2; judge && i <= k; i++)
{
if (n % i == 0) { judge = 0; }
}
return judge;
}
int main()
{
int x = 0, y = 0, number = 0, num1 = 0, num2 = 0;
for (int number=4; number<=2000;number+=2)
{
for (x = 2; x < number / 2; x++)
{
num1 = x;
if (judgePrime(num1) == 0)
{
num1 = 0;
}
num2 = number - x;
if (judgePrime(num2) == 0)
{
num2 = 0;
}
if (num1 && num2)
{
printf(" %4d = %2d + %d\n", number, num1, num2);
break;
}
}
}
return 0;
}
编程序exp4_7.c,用递归方法实现求解两个整数的最大公约数,并与迭代方法作比较。
实验解答:
#include
int gcd(int m, int n)
{
if (m > n)
return gcd(m - n, n);
else if (m < n)
return gcd(m, n - m);
else if (m == n)
return m;
}
int main()
{
int m, n;
printf("Input m,n:\n");
scanf_s("%d%d", &m, &n);
printf("GCD is: %d\n", gcd(m, n));
}
你输入的数据 你程序的输出结果
12 6 GCD is: 6
348 3 GCD is: 3
90 8 GCD is: 2
24 8 GCD is: 8
用调试器观察程序exp4_8.c的运行过程,并记录各种变量在每一步执行时的变化情况,在表格中填写每一个跟踪步每个变量对应的值。程序代码如下。
#include
int a = 1;
int f(int a)
{
auto int b = 2;
static int c = 3;
a = a+1;
b = b+1;
c = c+1;
return (a+b+c);
}
int main()
{
int i;
for (i=0;i<3;i++)
{
a = a+2;
printf("%d \n",f(a));
}
return 0;
}
提示:首先选择“调试”菜单,再选择“窗口”子菜单,再选择打开“监视1”窗口,在其中输入&a、&b、&c、&i进行观察,点开这些地址符前面的+号,就可以看到对应变量的值,注意观察地址值的变化以区分目前空间是哪个变量在作用域,尤其同名变量。下表中在某位置该变量不可见则不填内容。
| 跟踪点(黄色跟踪箭头指在这一行) | 全局变量a | f的形参a | f 自动局部变量b | f 静态局部变量c | 主函数的i |
|---|---|---|---|---|---|
| main函数的左大括号处 | 1 | ||||
| 第1次for行 | 1 | -858993460 | |||
| a = a+2; | 1 | 0 | |||
| printf行 | 3 | 0 | |||
| 按F11到f函数左大括号处 | 3 | 3 | |||
| auto int b = 2; | 3 | -858993460 | 3 | ||
| a = a+1; | 3 | 2 | 3 | ||
| b = b+1; | 4 | 2 | 3 | ||
| c = c+1; | 4 | 3 | 3 | ||
| return (a+b+c); | 4 | 3 | 4 | ||
| 第1次f函数右大括号处 | 4 | 3 | 4 | ||
| 按F10回到主函数的printf行 | 3 | 0 | |||
| 按F10到第2次for行 | 3 | 0 | |||
| a = a+2; | 3 | 1 | |||
| printf行 | 5 | 1 | |||
| 按F11到f函数左大括号处 | 5 | 4 | |||
| auto int b = 2; | 5 | -858993460 | 4 | ||
| a = a+1; | 5 | 2 | 4 | ||
| b = b+1; | 6 | 2 | 4 | ||
| c = c+1; | 6 | 3 | 4 | ||
| return (a+b+c); | 6 | 3 | 5 | ||
| 第2次f函数右大括号处 | 6 | 3 | 5 | ||
| 按F10回到主函数的printf行 | 5 | 1 | |||
| 按F10到第3次for行 | 5 | 1 | |||
| a = a+2; | 5 | 2 | |||
| printf行 | 7 | 2 | |||
| 按F11到f函数左大括号处 | 7 | 5 | |||
| auto int b = 2; | 7 | -858993460 | 5 | ||
| a = a+1; | 7 | 2 | 5 | ||
| b = b+1; | 8 | 2 | 5 | ||
| c = c+1; | 8 | 3 | 5 | ||
| return (a+b+c); | 8 | 3 | 6 | ||
| 第3次f函数右大括号处 | 8 | 3 | 6 | ||
| 按F10回到主函数的printf行 | 7 | 2 | |||
| 按F10到第4次for行 | 7 | 2 | |||
| 主函数的return 0;处 | 7 | 3 |