第二章练习答案
2-1
** List2-5是一个用秒数来表示程序开始后经过的时间的程序。请改写程序,令其不仅能用秒数,还能用时钟数来表示时间。**
cpp
#include <stdio.h>
#include <time.h>
int sleep(unsigned long x)
{
clock_t c1 = clock(), c2;
do
{
if ((c2 = clock()) == (clock_t)-1) // 错误
return 0;
} while (1000.0 * (c2 - c1) / CLOCKS_PER_SEC < x);
return 1;
}
int main()
{
for (int i = 10; i > 0; i--)
{
// 打印剩余时间和当前时钟周期数
printf("\r %2d seconds | Clock ticks: %lu", i, clock());
fflush(stdout);
sleep(1000); // 等待 1000 毫秒(1 秒)
}
printf("\r\afire\n");
return 0;
}
2-2
** 编写一个函数,令其能从字符串开头逐一显示字符。
void gput(const char *s, int speed);
在这里,s是要显示的字符串,speed是以毫秒为单位的显示速度。例如调用以下代码,首先会显示A',100毫秒后显示!0!,再过100毫秒后显示!C'。当显示完"ABC"字符串的所有字符后,返回到调用方。gput("ABC",100);
**
cpp
// 模拟等待 x 毫秒
int sleep(unsigned long x)
{
clock_t c1 = clock(), c2;
do
{
if ((c2 = clock()) == (clock_t)-1) // 错误
return 0;
} while (1000.0 * (c2 - c1) / CLOCKS_PER_SEC < x);
return 1;
}
// 从字符串开头逐一显示字符
void gput(const char* s, int speed)
{
while (*s)
{
putchar(*s++);
fflush(stdout); // 刷新输出缓冲区
sleep(speed); // 等待指定的毫秒数
}
}
int main()
{
gput("ABC", 100); // 调用示例
return 0;
}
2-3
** 编写一个闪烁显示字符串的函数。
void bput(const char *s, int d,int e, int n);
字符串s显示a毫秒后,消失e毫秒,反复执行上述操作n次后返回到调用方。※不妨假设字符串s只有一行(即不包含换行符等符号,而且字符串的长度小于控制台画面的宽度)。**
cpp
#include <stdio.h>
#include <string.h>
#include <time.h>
// 模拟等待 x 毫秒
int sleep(unsigned long x)
{
clock_t c1 = clock(), c2;
do
{
if ((c2 = clock()) == (clock_t)-1) // 错误
return 0;
} while (1000.0 * (c2 - c1) / CLOCKS_PER_SEC < x);
return 1;
}
// 闪烁显示字符串的函数
void bput(const char* s, int d, int e, int n)
{
for (int i = 0; i < n; i++)
{
// 显示字符串
printf("\r%s", s);
fflush(stdout); // 刷新输出缓冲区
sleep(d); // 等待指定的显示时间
// 清除字符串
printf("\r%*s", (int)strlen(s), "");
fflush(stdout); // 刷新输出缓冲区
sleep(e); // 等待指定的消失时间
}
}
int main()
{
bput("Hello, World!", 500, 500, 10); // 示例调用
return 0;
}
2-4
编写一个如字幕般显示字符串的函数。
void telop(const char *s,int direction,int speed,int-n);
其中,s是要显示的字符串,direction是字幕滚动的方向(从右往左是0,从左往右是1),speed是以毫秒为单位的速度,n是显示次数。※不妨假设字符串s只有一行。
cpp
#include <stdio.h>
#include <string.h>
#include <time.h>
// 模拟等待 x 毫秒
int sleep(unsigned long x)
{
clock_t c1 = clock(), c2;
do
{
if ((c2 = clock()) == (clock_t)-1) // 错误
return 0;
} while (1000.0 * (c2 - c1) / CLOCKS_PER_SEC < x);
return 1;
}
// 字幕显示函数
void telop(const char* s, int direction, int speed, int n)
{
int len = strlen(s);
char buffer[256]; // 假设控制台宽度最大为256字符
for (int count = 0; count < n; count++)
{
if (direction == 0) // 从右往左
{
for (int i = 0; i < len; i++)
{
snprintf(buffer, sizeof(buffer), "%s%*s", s + i, len - i, "");
printf("\r%s", buffer);
fflush(stdout);
sleep(speed);
}
}
else if (direction == 1) // 从左往右
{
for (int i = len - 1; i >= 0; i--)
{
snprintf(buffer, sizeof(buffer), "%*s%s", len - i, "", s + i);
printf("\r%s", buffer);
fflush(stdout);
sleep(speed);
}
}
}
//printf("\r%*s", len, ""); // 清空最后显示的字符串
}
int main()
{
// 示例调用,从右往左滚动,速度为100毫秒,显示3次
telop("Hello, World!", 0, 100, 3);
// 示例调用,从左往右滚动,速度为100毫秒,显示3次
telop("Hello, World!", 1, 100, 3);
return 0;
}
2-5
** List2-13的"心算训练"程序显示的是进行10次加法运算所需要的时间。改写程序,令其能显示每次运算所需要的时间和运算的平均时间。**
cpp
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
int stage, i, a, b, c, x, n;
clock_t start_time[5], end_time[5]; // 用于记录每次运算的起始时钟和终止时钟
clock_t start, end;
clock_t start_per_time, end_per_time; // 每次心算时刻的起始时钟和终止时钟
srand(time(NULL)); // 设置随机数的种子
printf("扩大视野心算训练开始!!!\n");
start = clock(); // 记录训练开始时间
for (stage = 0; stage < 5; stage++) {
a = 10 + rand() % 90;
b = 10 + rand() % 90;
c = 10 + rand() % 90;
n = rand() % 17; // 生成0~16随机数
printf("%d%*s+%*s%d%*s+%*s%d: ", a, n, "", n, "", b, n, "", n, "", c);
start_per_time = clock(); // 记录当前运算开始时间
start_time[stage] = start_per_time;
do {
scanf("%d", &x);
if (x == a + b + c)
break;
printf("回答错误。请重新输入:");
} while (1);
end_per_time = clock(); // 记录当前运算结束时间
end_time[stage] = end_per_time;
}
end = clock(); // 记录训练结束时间
printf("5次运算总用时%.1f秒。\n", (double)(end - start) / CLOCKS_PER_SEC);
for (i = 0; i < 5; i++) {
printf("第%d次运算共用时%.1f秒\n", i + 1, (double)(end_time[i] - start_time[i]) / CLOCKS_PER_SEC);
}
printf("平均每次用时%.1f秒\n", (double)(end - start) / (CLOCKS_PER_SEC * 5));
return 0;
}
2-6
** 把上面的程序改写成能进行加法和减法运算的程序,每次随机决定进行哪种运算。也就是说,假设三个值是a、b、C,每次都通过随机数来从下列组合中选一个进行出题。a+b+c / a+b-c / a-b+c / a-b-c**
cpp
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
int stage;
int i;
int a, b, c;
int x;
int n;
int correct_answer;
clock_t start_time[5], end_time[5]; // 用于记录每次运算的起始时钟和终止时钟
clock_t start, end;
clock_t start_per_time, end_per_time; // 每次心算时刻的起始时钟和终止时钟
srand(time(NULL)); // 设置随机数的种子
printf("扩大视野心算训练开始!!!\n");
start = clock(); // 记录训练开始时间
for (stage = 0; stage < 5; stage++) {
a = 10 + rand() % 90;
b = 10 + rand() % 90;
c = 10 + rand() % 90;
n = rand() % 17; // 生成0~16随机数
int operation = rand() % 4; // 随机选择操作
switch (operation) {
case 0:
printf("%d%*s+%*s%d%*s+%*s%d: ", a, n, "", n, "", b, n, "", n, "", c);
correct_answer = a + b + c;
break;
case 1:
printf("%d%*s+%*s%d%*s-%*s%d: ", a, n, "", n, "", b, n, "", n, "", c);
correct_answer = a + b - c;
break;
case 2:
printf("%d%*s-%*s%d%*s+%*s%d: ", a, n, "", n, "", b, n, "", n, "", c);
correct_answer = a - b + c;
break;
case 3:
printf("%d%*s-%*s%d%*s-%*s%d: ", a, n, "", n, "", b, n, "", n, "", c);
correct_answer = a - b - c;
break;
}
start_per_time = clock(); // 记录当前运算开始时间
start_time[stage] = start_per_time;
do {
scanf("%d", &x);
if (x == correct_answer)
break;
printf("回答错误。请重新输入:");
} while (1);
end_per_time = clock(); // 记录当前运算结束时间
end_time[stage] = end_per_time;
}
end = clock(); // 记录训练结束时间
printf("5次运算总用时%.1f秒。\n", (double)(end - start) / CLOCKS_PER_SEC);
for (i = 0; i < 5; i++) {
printf("第%d次运算共用时%.1f秒\n", i + 1, (double)(end_time[i] - start_time[i]) / CLOCKS_PER_SEC);
}
printf("平均每次用时%.1f秒\n", (double)(end - start) / (CLOCKS_PER_SEC * 5));
return 0;
}