20201022-成信大-C语言程序设计-20201学期《C语言程序设计B》C-trainingExercises07
P702
/*
自行扩展
输入任意年【1-3000年】月【1-12月】,给出该月的天数
分析:
1. 2003年不是闫年,额外知识点:
return (year % (year % 100 ? 4 : 400) ? 0 : 1);
2. 一,三,五,七,八,十,十二月,各31天
二为28天,如果是闫年,则29天
四,六,九,十一朋,为各30天
3. 输入N,直接判断匹配对应的天数即可
4. 本题可以扩展为输入任意某年某月,输出该月的天数
*/
#include <stdio.h>
int main(void)
{
int year;
int month;
printf("please input the year,month number: ");
scanf("%d,%d",&year, &month);
if (( year >1 && year< 3000) && (month>0 && month < 13))
{
// 先判断是否闫年
if((year % (year % 100 ? 4 : 400) ? 0 : 1))
{
// 从技术上讲,可以首先约束到有效月数字上来
if(month == 2 )
{
printf("\n%d.%d has 29 days", year, month);
}
else if(month == 4 || month==6||month==9||month==11)
{
printf("\n%d.%d has 30 days", year, month);
}
else
{
printf("\n%d.%d has 31 days", year, month);
}
}
else
{
// 从技术上讲,可以首先约束到有效月数字上来
if(month == 2 )
{
printf("\n%d.%d has 28 days", year, month);
}
else if(month == 4 || month==6||month==9||month==11)
{
printf("\n%d.%d has 30 days", year, month);
}
else
{
printf("\n%d.%d has 31 days", year, month);
}
}
}
else
{
printf("\nInvalid year or month input !");
}
return 0;
}
另一种解法
/*
自行扩展
输入任意年【1-3000年】月【1-12月】,给出该月的天数
再重构一下程序,相同的部分,可以只用一次
分析:
1. 2003年不是闫年,额外知识点:
return (year % (year % 100 ? 4 : 400) ? 0 : 1);
2. 一,三,五,七,八,十,十二月,各31天
二为28天,如果是闫年,则29天
四,六,九,十一朋,为各30天
3. 输入N,直接判断匹配对应的天数即可
4. 本题可以扩展为输入任意某年某月,输出该月的天数
学习方法:
1. 通过思考,不断重构自己的代码,让程序更简洁
2. 让重复的代码被重构
*/
#include <stdio.h>
int main(void)
{
int year;
int month;
printf("please input the year,month number: ");
scanf("%d,%d", &year, &month);
if ((year > 1 && year < 3000) && (month > 0 && month < 13))
{
// 其他月份,正常输出
if (month == 4 || month == 6 || month == 9 || month == 11)
{
printf("\n%d.%d has 30 days", year, month);
}
else if (month == 2) // 只有2月,才去判断是否闫年
{
if ((year % (year % 100 ? 4 : 400) ? 0 : 1))
{
printf("\n%d.%d has 29 days", year, month);
}
else
{
printf("\n%d.%d has 28 days", year, month);
}
}
else
{
printf("\n%d.%d has 31 days", year, month);
}
}
else
{
printf("\nInvalid year or month input !");
}
return 0;
}
多一种思路
/*
编写一程序P702.C实现以下功能
输入月份,输出2003年该月有几天。当输入的月份超范围时,应输出“Invalid month input”。.
编程可用素材:
printf("please input the month number: ")、
printf("\nInvalid month input !\n")、
printf("\n2003.… has … days\n"…。
程序的运行效果应类似地如图1和图2所示,图中的红色部分是从键盘输入的内容。
please input the month number: 4
2003.4 has 30 days
图1 程序运行效果示例(输入月份合法)
please input the month number: 13
Invalid month input !
分析:
1. 2003年不是闫年,额外知识点:
return (year % (year % 100 ? 4 : 400) ? 0 : 1);
2. 一,三,五,七,八,十,十二月,各31天
二为28天,如果是闫年,则29天
四,六,九,十一朋,为各30天
3. 输入N,直接判断匹配对应的天数即可
4. 本题可以扩展为输入任意某年某月,输出该月的天数
*/
#include <stdio.h>
int main(void)
{
int month;
printf("please input the month number: ");
scanf("%d", &month);
// 从技术上讲,可以首先约束到有效月数字上来
if(month<1 || month >12)
{
printf("\nInvalid month input !");
}
else if(month == 2 )
{
printf("\n2003.2 has 28 days");
}
else if(month == 4 || month==6||month==9||month==11)
{
printf("\n2003.%d has 30 days", month);
}
else
{
printf("\n2003.%d has 31 days", month);
}
return 0;
}
P754
/*
编写一程序P754.C实现以下功能
从键盘输入一个一百分制成绩(无小数),将输入的数据
转换成等级‘ABCDEFGHIJX’:
90~100分为‘A’,
80~89分为‘B’,
70~79分为‘C’,
60~69分为‘D’,
50~59分为‘E’,
40~49分为‘F’,
30~39分为‘G’,
20~29分为‘H’,
10~19分为‘I’,
0~9分为‘J’,
其它输入超正常范围分数的则为‘X’。
编程可用素材:
printf("please input the score(0-100): ")、
printf("\nscore=…, grade=…。
程序的运行效果应类似地如图1、图2所示,图中的红色部分是从键盘输入的内容。
please input the score(0-100): 55
score=55, grade=E
图1 程序运行效果示例
please input the score(0-100): -93
score=-93, grade=X
分析:
1. 可以使用if进行多分支判断
2. 可以使用switch进行多分支判断
注意使用break;
注意使用default;
*/
#include <stdio.h>
int main(void)
{
int score;
printf("please input the score(0-100): ");
scanf("%d", &score);
switch(score / 10)
{
case 10:
if(score > 100)
{
printf("\nscore=%d, grade=X", score);
break;
}
case 9:
printf("\nscore=%d, grade=A", score);
break;
case 8:
printf("\nscore=%d, grade=B", score);
break;
case 7:
printf("\nscore=%d, grade=C", score);
break;
case 6:
printf("\nscore=%d, grade=D", score);
break;
case 5:
printf("\nscore=%d, grade=E", score);
break;
case 4:
printf("\nscore=%d, grade=F", score);
break;
case 3:
printf("\nscore=%d, grade=G", score);
break;
case 2:
printf("\nscore=%d, grade=H", score);
break;
case 1:
printf("\nscore=%d, grade=I", score);
break;
case 0:
if(score < 0)
{
printf("\nscore=%d, grade=X", score);
break;
}
else
{
printf("\nscore=%d, grade=J", score);
break;
}
default:
printf("\nscore=%d, grade=X", score);
}
return 0;
}
另一种解法
/*
编写一程序P754.C实现以下功能
从键盘输入一个一百分制成绩(无小数),将输入的数据
转换成等级‘ABCDEFGHIJX’:
90~100分为‘A’,
80~89分为‘B’,
70~79分为‘C’,
60~69分为‘D’,
50~59分为‘E’,
40~49分为‘F’,
30~39分为‘G’,
20~29分为‘H’,
10~19分为‘I’,
0~9分为‘J’,
其它输入超正常范围分数的则为‘X’。
编程可用素材:
printf("please input the score(0-100): ")、
printf("\nscore=…, grade=…。
程序的运行效果应类似地如图1、图2所示,图中的红色部分是从键盘输入的内容。
please input the score(0-100): 55
score=55, grade=E
图1 程序运行效果示例
please input the score(0-100): -93
score=-93, grade=X
分析:
1. 可以使用if进行多分支判断
2. 可以使用switch进行多分支判断
注意使用break;
注意使用default;
*/
#include <stdio.h>
int main(void)
{
int score;
printf("please input the score(0-100): ");
scanf("%d", &score);
if(score <0 || score>100)
{
printf("score=%d, grade=X", score);
}
else
{
switch(score / 10)
{
case 10:
case 9:
printf("score=%d, grade=A", score);
break;
case 8:
printf("score=%d, grade=B", score);
break;
case 7:
printf("score=%d, grade=C", score);
break;
case 6:
printf("score=%d, grade=D", score);
break;
case 5:
printf("score=%d, grade=E", score);
break;
case 4:
printf("score=%d, grade=F", score);
break;
case 3:
printf("score=%d, grade=G", score);
break;
case 2:
printf("score=%d, grade=H", score);
break;
case 1:
printf("score=%d, grade=I", score);
break;
case 0:
printf("score=%d, grade=J", score);
break;
}
}
return 0;
}
P112
/*
编写一程序P112.C实现以下功能
设某企业2006年的产值为5000万,计划以后每年的增长率为x(x从键盘输入,
例如输入8.75表示8.75%),计算该企业的产值在哪年实现翻番以及翻番时的产值,然后输出(输出时以万为单位,应考虑有小数)。
编程可用素材:
printf("Please input x: ")、
printf("\nyear = … nian, chanzhi = …。
程序的运行效果应类似地如图1所示,图中的红色部分是从键盘输入的内容。
Please input x: 50.6
year = 2008 nian, chanzhi = 11340.18
*/
#include <stdio.h>
int main(void)
{
int year = 2006;
double gdp = 5000;
double rate;
printf("Please input x: ");
scanf("%lf", &rate);
rate = rate / 100;
while(gdp < 10000)
{
gdp = gdp * (1 + rate);
year++;
}
printf("\nyear = %d nian, chanzhi = %.2lf", year, gdp);
return 0;
}
P793
/*
编写一程序P793.C实现以下功能
从键盘读入一个数n(必须使用long int),先逆序输出n的各位数,再输出n的各位数之和。
编程可用素材:
printf("请输入一个数:")、
printf("\n该数的各位数之逆序为:")、
printf("\n该数的各位数之和为:%d\n"…。
程序的运行效果应类似地如图1所示,图1中的红色部分是从键盘输入的内容。
请输入一个数:1234567
该数的各位数之逆序为:7654321
该数的各位数之和为:28
易错点:
1. 要特别注意,最低几位为0时,置于高位就没有了
高位有0,没关系
中间有0,没关系
末尾有0,转过来,就是高位,要注意补0输出
*/
#include <stdio.h>
int main(void)
{
int flag = 1;
int countZero = 0; // 低位为0计数器
long int data;
double rdata = 0;
long int sum = 0;
printf("请输入一个数:");
scanf("%ld", &data);
while (data > 0)
{
if (data % 10)
{
flag = 0; // 出现第一个非零的末尾数时,标志位置0
}
else
{
if(flag)
{
// 只取最开始的那一些最低位取出来是 0 ,则反序输出时,补计数的0
// 中间位,高位不管
countZero++;
}
}
sum += data % 10; // 逐个只取出个位求和
rdata = rdata * 10 + data % 10; // 逐个计算翻转数
data = data / 10; // 逐个丢掉个位
}
if(countZero)
{
printf("\n该数的各位数之逆序为:");
while(countZero)
{
printf("0");
countZero--;
}
printf("%.0lf", rdata);
printf("\n该数的各位数之和为:%ld", sum);
}
else
{
printf("\n该数的各位数之逆序为:%.0lf", rdata);
printf("\n该数的各位数之和为:%ld", sum);
}
return 0;
}
但是,上面的代码,没有考虑到数据为负数的情况
以下是另一个参考,更合理
/*
编写一程序P793.C实现以下功能
从键盘读入一个数n(必须使用long int),先逆序输出n的各位数,再输出n的各位数之和。
编程可用素材:
printf("请输入一个数:")、
printf("\n该数的各位数之逆序为:")、
printf("\n该数的各位数之和为:%d\n"…。
程序的运行效果应类似地如图1所示,图1中的红色部分是从键盘输入的内容。
请输入一个数:1234567
该数的各位数之逆序为:7654321
该数的各位数之和为:28
易错点:
1. 要特别注意,最低几位为0时,置于高位就没有了
高位有0,没关系
中间有0,没关系
末尾有0,转过来,就是高位,要注意补0输出
2. 考虑到用户输入的是负数呢
3. 输出每一位的时候,可以一边分离出来,一边输出,工作量更节省一些
*/
#include <stdio.h>
#include <stdlib.h> // 用于labs函数
int main() {
long int n;
printf("请输入一个数:");
scanf("%ld", &n); // 读取长整数
long int num = labs(n); // 处理负数,取绝对值
int sum = 0;
printf("\n该数的各位数之逆序为:");
if (num == 0) { // 处理输入为0的特殊情况
printf("0");
} else {
while (num > 0) {
int digit = num % 10; // 提取最后一位
printf("%d", digit); // 逆序输出,边处理边输出
sum += digit; // 累加求和
num /= 10; // 去掉最后一位
}
}
printf("\n该数的各位数之和为:%d\n", sum); // 输出总和
return 0;
}
P744
/*
编写一程序P744.C实现以下功能
(1)从键盘输入一个一百分制成绩,如果不在0~100范围内,则要求重新输入数据,直到输入的数据在0~100范围内。
(2)将输入的数据转换成等级‘A’,‘B’,‘C’,‘D’,‘E’。
90分以上为‘A’,80~89分为‘B’,70~79分为‘C’,60~69分为‘D’,60分以下为‘E’。
(3)要求使用switch、case、default语句,结果赋值给变量grade,并将变量grade的值输出到屏幕上。
(4)变量数据类型的选择应适当,在保证满足设计要求精度的情况下,养成不浪费内存空间和计算时间的好习惯。
编程可用素材:
printf("please input the score(0-100): ")、
printf("\nscore=…,grade=…。
程序的运行效果应类似地如图1所示,图1中的红色部分是从键盘输入的内容。
please input the score(0-100): 103
please input the score(0-100): 55.3
score=55.3,grade=E
知识点
1. 表达式计算的结果,需要是一个整数
2. case 之后,是一个常量
3. 有无break的差别
4. default是其他情况
在使用switch语句时还应注意以下几点:
1. 在case后的各常量表达式的值不能相同,否则会出现错误。
2. 在case后,允许有多个语句,可以不用{}括起来。
3. 各case和default子句的先后顺序可以变动,而不会影响程序执行结果。
4. default子句可以省略不用。
*/
#include <stdio.h>
int main(void)
{
float score;
char grade;
int tmp;
do
{
printf("please input the score(0-100): ");
scanf("%f", &score);
} while (score < 0 || score > 100);
tmp = (int)score / 10;
switch (tmp)
{
case 10:
case 9:
grade = 'A';
break;
case 8:
grade = 'B';
break;
case 7:
grade = 'C';
break;
case 6:
grade = 'D';
break;
default:
grade = 'E';
}
printf("\nscore=%.1f,grade=%c", score, grade);
return 0;
}