1. 前言
本篇我们讲解2个月搞定计算机二级C语言——真题 5

2. 程序填空题
2.1 题目要求

2.2 提供的代码
#include <stdio.h> double fun(int n) { int i; double s, t; /**********found**********/ s = __1__; /**********found**********/ for (i = 1; i <= __2__; i++) { t = 2.0 * i; /**********found**********/ s = s + (2.0 * i - 1) * (2.0 * i + 1) / __3__; } return s; } main() { int n = -1; while (n < 0) { printf("Please input(n>0): "); scanf("%d", &n); } printf("nThe result is: %fn", fun(n)); getchar(); }
2.3 解题思路
这道题就是典型的纸老虎题,它作为编程的第一题定会在考场上压力你一下,在题目上做做文章,搞得这道题好像很难的样子,其实主要的代码都写完了,而且也给出了式子的规律,那么我们只需略微出手,便可拿下此题。
第 (1) 处填空:
此处是给变量 s 赋值,可以看到在 fun() 函数的末尾是 return s; 将其作为函数返回值返回,由此可以得出 s 是保存前 n 项和的变量,所以这里我们给它赋值为 0,做一个变量初始化,防止程序开始运行时 s 存储的是垃圾值。
s = 0; // 初始化为 0
第 (2) 处填空:
这里缺一个循环的条件,在题目所给的式子中是从 1 计算到 n 的,循环中 i 做的就是这件事情,所以 i小于等于形参 n 时符合条件,此处填 n。
for (i = 1; i <= n; i++) { // 1 ~ n
第 (3) 处填空:
我们单独看这个式子 (2.0 * i - 1) * (2.0 * i + 1) / __3__,此处可以和题目最后的式子规律一一对应,空缺的第 3 处对应着式子的分母部分 (2*n)²。变量 t 在循环开始时通过 t = 2.0 * i; 已经完成了分母括号里的计算,我们只需使用 t * t 计算平方即可。
s = s + (2.0 * i - 1) * (2.0 * i + 1) / (t * t); // 计算 t 乘 t,即 t 的平方
当然计算平方也可以使用 C 语言标准库里的函数——pow 函数,它可以用于计算幂次,定义在 math.h 头文件中,使用需要包含头文件。
// C 库函数 double pow(double x, double y) 返回 x 的 y 次幂,即 x ^ y #include <math.h> // 使用 pow 函数时需要包含 math.h 头文件 s = s + (2.0 * i - 1) * (2.0 * i + 1) / pow(t, 2); // 计算 t 的 2 次幂,即 t 的平方
题目要求不要改动其他函数,不得增行或删行,所以这里我继续使用 t * t 计算平方,平时编程时可以直接用 pow 函数。
2.4 代码实现
填写完整的代码:
#include <stdio.h> double fun(int n) { int i; double s, t; /**********found**********/ s = 0; // 初始化为 0 /**********found**********/ for (i = 1; i <= n; i++) { // 1 ~ n t = 2.0 * i; /**********found**********/ s = s + (2.0 * i - 1) * (2.0 * i + 1) / (t * t); // 计算 t 乘 t,即 t 的平方 } return s; } int main() { int n = -1; while (n < 0) { printf("Please input(n>0): "); scanf("%d", &n); } printf("nThe result is: %fn", fun(n)); getchar(); }
提示:为确保代码正常运行,请在题库编程环境的对应题目中进行测试和运行。
3. 程序修改题
3.1 题目要求

3.2 提供的代码
#include <stdio.h> #pragma warning(disable : 4996) int my_isalpha(char c) { if (c >= 'A' && c <= 'Z') return 1; else if (c >= 'a' && c <= 'z') return -1; else return 0; } void a() { char ch; int sort; printf("本程序判断你从键盘上键入字符的种类,请输入字符(串):n"); do { ch = getchar(); if (ch != 'n') { sort = my_isalpha(ch); /**********************found***********************/ switch (-1 <= sort && sort <= 1) { case 1: printf("%c", '*'); break; /**********************found***********************/ case -1: printf("%c", '#'); case 0: printf("%c", '?'); } } /**********************found***********************/ } while (ch == 'n'); printf("%c", 'n'); } void main() { a(); }
3.3 解题思路
这道题主要考察 switch 语句的用法。
第 (1) 处修改:
switch 括号中的表达式(即控制表达式)必须是整型或能转换为整型的类型。case 标签也必须是常量表达式,并且必须与 switch 的控制表达式类型兼容。
所以不需要那一堆的关系、逻辑运算,只需放入 sort 就好,它存储着 my_isalpha 函数的返回值。
switch (sort) {
第 (2) 处修改:
在 switch 语句中,break 语句用于终止当前 case 分支的执行,并跳出 switch 语句,避免程序继续执行后续的 case 分支。
在改好第一处后,运行程序输入一个小写字母,返回的是 #?,这是因为此处的 case -1: 的分支没有加 break 语句,导致不能跳出 switch 语句,在执行完 case -1: 分支后又执行了 case -1: 分支,显然我们程序没有按照我们的想法运行。
这时我们需要将两个分支分别加上 break 语句即可。
我们在后续的程序开发中可以再加上 default 分支,用来执行不在条件内的操作,从而增强程序的健壮性。
case -1: printf("%c", '#'); break; case 0: printf("%c", '?'); break;
第 (3) 处修改:
do while 语句会先执行一遍循环中的程序,再判断循环条件是否为真,真则继续循环,否则执行循环后面的程序。
ch 存储的是键盘输入的单个字符,'n' 是一个转义序列,用于表示换行符,对应键盘上的回车键(Enter)。
这里我没找出什么错误,提供的代码是 while (ch == 'n');,改的话只能改成 while (ch != 'n');,这两个代码我分别提交后都可以得满分。
分别运行这两个程序,如果按照要求先输入字符再敲回车这两个程序是没有任何区别的。
但是没有先输入字符直接敲回车,那么区别就来了:while (ch == 'n'); 不论你敲多少次回车,这个循环都不停止,因为符合ch == 'n'这个条件,它会一直循环到你输入不是回车的字符。
do { ch = getchar(); if (ch != 'n') { // …… } /**********************found***********************/ } while (ch == 'n');
而while (ch != 'n');呢?如果你第一次敲回车此时ch存储的是回车的转义字符'n',循环条件是ch != 'n',由于循环条件不符合,所以不会进行下一次循环,而是执行while下面的语句了。
do { ch = getchar(); if (ch != 'n') { // …… } /**********************found***********************/ } while (ch != 'n');
这就是它俩的区别所在,大家以后编程时需要注意循环/判断的条件哦。
3.4 代码实现
修改后的代码:
#include <stdio.h> #pragma warning(disable : 4996) int my_isalpha(char c) { if (c >= 'A' && c <= 'Z') return 1; else if (c >= 'a' && c <= 'z') return -1; else return 0; } void a() { char ch; int sort; printf("本程序判断你从键盘上键入字符的种类,请输入字符(串):n"); do { ch = getchar(); if (ch != 'n') { sort = my_isalpha(ch); /**********************found***********************/ switch (sort) { case 1: printf("%c", '*'); break; /**********************found***********************/ case -1: printf("%c", '#'); break; case 0: printf("%c", '?'); break; } } /**********************found***********************/ } while (ch != 'n'); printf("%c", 'n'); } void main() { a(); }
提示:为确保代码正常运行,请在题库编程环境的对应题目中进行测试和运行。
4. 程序设计题
4.1 题目要求

4.2 提供的代码
#include <stdio.h> #pragma warning(disable : 4996) double fun(int n) { } main() { int n; double s; void NONO(); printf("Input n: "); scanf("%d", &n); getchar(); s = fun(n); printf("s=%fn", s); NONO(); getchar(); } void NONO() { /* 请在此函数内打开文件,输入测试数据,调用 fun 函数,输出数据,关闭文件。 */ FILE * rf, *wf; int n, i; double s; rf = fopen("in.dat", "r"); wf = fopen("out.dat", "w"); for (i = 0; i < 10; i++) { fscanf(rf, "%d", &n); s = fun(n); fprintf(wf, "%lfn", s); } fclose(rf); fclose(wf); }
4.3 解题思路
题目要求计算多项式的值,给定多项式的第一项为 1,第二项到第 n 项是计算阶乘倒数的和。
我们可以用Sn作为存储累加和的变量,之后通过循环累乘得到阶乘的值,最后计算每一项阶乘的倒数并累加至Sn。
在提交时出现了一点小问题,程序可以正常运行,但提交时判为 0 分。经过测试只要把 main 函数里的NONO();语句注释再提交就好了。
4.4 代码实现
填写完整的代码:
#include <stdio.h> #pragma warning(disable : 4996) double fun(int n) { int i = 0; double Sn = 1.0; // 存储累加和,多项式的第一项为 1 unsigned long factorial = 1; for (i = 1; i <= n; i++) { // 遍历 1~n,注意 i 从 1 开始 factorial *= i; // 分别计算从 1~n 的阶乘 Sn += 1.0 / factorial; // 计算阶乘的倒数,并加到累加和变量中 } return Sn; } main() { int n; double s; void NONO(); printf("Input n: "); scanf("%d", &n); getchar(); s = fun(n); printf("s=%fn", s); NONO(); // 如果评分没过,把这句注释了再提交就可以了 getchar(); } void NONO() { /* 请在此函数内打开文件,输入测试数据,调用 fun 函数,输出数据,关闭文件。 */ FILE * rf, *wf; int n, i; double s; rf = fopen("in.dat", "r"); wf = fopen("out.dat", "w"); for (i = 0; i < 10; i++) { fscanf(rf, "%d", &n); s = fun(n); fprintf(wf, "%lfn", s); } fclose(rf); fclose(wf); }
提示:为确保代码正常运行,请在题库编程环境的对应题目中进行测试和运行。
5. 后记
本篇博客到这就结束了,如果您有疑问或建议欢迎您在留言区留言。