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: %f\n", 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: %f\n", 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=%f\n", 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, "%lf\n", 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=%f\n", 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, "%lf\n", s);
}
fclose(rf);
fclose(wf);
}
提示:为确保代码正常运行,请在题库编程环境的对应题目中进行测试和运行。
5. 后记
本篇博客到这就结束了,如果您有疑问或建议欢迎您在留言区留言。