编写一个C程序,计算4个整数的最大值,最小值,总和和平均值。
这 程序以十进制,十六进制或八进制格式读取4个整数,并指定一个字符 从命令提示符处进行数学运算(x表示最大值,m表示最小值,s表示总和,a表示平均值) (在Ubuntu上为xterminal)并输出操作结果。
输入/输出格式详细信息为 在下面提供。
对于x,m和s操作,结果应打印为整数;但作为浮点数 平均(a)操作。
整数输出将以十六进制格式打印,而浮动 点值将以科学格式打印。 输入:
<number 1>[space] <number 2>[space] <number 3>[space] <number 4>[space] <operation>
样本输入1:0xFF 99077 0 s,预期输出1:0x1a1
样本输入2:0x10 10 10 010 a,预期输出2:1.100000e + 01
样品输入3:0770 0xFF 270 0xAB m,预期输出3:0xab
样本输入4:010 0x10 10 0x3 x,预期输出4:0x10
这是我编写的代码
#include <stdio.h>
int main() {
int num1, num2, num3, num4;
char op;
scanf("%d%d%d%d%c", &num1, &num2, &num3, &num4, &op);
switch (op)
{
case'x':
if (num1 > num2&&num1 > num3&&num1 > num4)
printf("%d", num1);
else if (num2 > num1&&num2 > num3&&num2 > num4)
printf("%d", num2);
else if (num3 > num1&&num3 > num1&&num3 > num4)
printf("%d", num3);
else
printf("%d", num4);
break;
case'm':
if (num1 < num2&&num1 < num3&&num1 < num4)
printf("%d", num1);
else if (num2 < num1&&num2 < num3&&num2 < num4)
printf("%d", num2);
else if (num3 < num1&&num3 < num1&&num3 < num4)
printf("%d", num3);
else
printf("%d", num4);
break;
case's':
printf("%d", num1 + num2 + num3 + num4);
break;
case'a':
printf(" %f", (num1 + num2 + num3 + num4) / 4);
break;
}
return 0;
}
答案 0 :(得分:3)
您需要在%d之间添加空格。此处很好地说明了为什么需要space的原因。这样代码就会变成
scanf("%d %d %d %d %c",&num1,&num2,&num3,&num4,&op);
要以十六进制格式打印,您需要使用“%x”表示。
printf("%x",num1);
要以科学格式打印,请使用“%.10e”
printf("%.10e",num1);
另一件事,为了得到一个除法浮点数,并且每个数字都是整数,您需要至少使分子或分母成为浮点。 就您而言,
printf("%.10e"(num1+num2+num3+num4)/4.0);
答案 1 :(得分:0)
在printf("0x%2x", op);
之后添加scanf()
会导致0x20
被打印出来。
0x20
是空格字符的十六进制值,因此证实了我们的怀疑,即正在读取空格字符而不是所需的运算符。
用scanf()
替换%d%d%d%d%c
(%d%d%d%d %c
)中的格式字符串会导致该方法正常工作,因为空格字符现在在运算符之前已被忽略。
输入:1 2 3 4 x
输出:4
答案 2 :(得分:0)
正如Tau和Toby所指出的那样,您在%c
调用中的scanf()
转换说明符将读取最后一个数字和运算符之间的第一个空白字符。
%c
是转换运算符中的一种特殊情况:大多数其他转换默认情况下会跳过空格,直到它们遇到非空格字符为止。对于具有换行符的用户输入或具有不同列间空白量的列表文本数据,这是有意义的:您想读取下一个数字或单词,而对空格不感兴趣。
%c
仅读取下一个字符,包括空格等;这对自己动手分析很有用。
有两种简单的方法可以解决此问题。
侵入性较小的一种是在%c
:scanf("%d%d%d%d %c", &num1, &num2, &num3, &num4, &op);
之前添加一些空间。单个空格是格式字符串中的“指令”,指示scanf
跳过全部空格,直到找到非空格字符为止。 (有关规范的带注释的引用,请参见下文。)程序中的其他所有内容都无需更改。
您还可以使用%s
读取字符串并检查其第一个字符。 %s
用于读取下一个单词,因此会自动跳过空格。但是,您需要注意太长的用户输入:它既不会溢出您正在使用的缓冲区,也不能留在输入中并混淆以后的scanf
。我们将字符串长度限制为1,但要提供2个字符的空格,因为scanf
将以空字符终止字符串。我们将忽略由于程序终止而无法读取的输入。示例:
// ...
char op[2] = {'\0', '\0'}; // space for the `'\0'`
// Read a string of length 1 (just a single char, in effect)
int numScanned = scanf("%d%d%d%d%1s", &num1, &num2, &num3, &num4, op);
switch (op[0]) // switch on first char in the array
{
case'x':
// ...
}
num3 > num1&&num3 > num1&&num3 > num4)
和另一个逻辑表达式具有两个冗余项(num3 > num1
)。
在具有较低优先级的操作数和运算符之间插入空格也将提高可读性,例如:
num3 > num1 && num3 > num4)
。
有些人即使在多余的子表达式上都加上了括号,但我不是那个朋友。
最后一个printf
中最后一个浮点格式转换是错误的,因为参数表达式的类型为int
;也许您想将一个整数转换为浮点数?这将导致所有int被提升为浮点并产生浮点结果:
printf(" %f", ((float)num1 + num2 + num3 + num4) / 4);
请注意,转换完整结果还不够:您仍将执行整数除法,将其舍入为较低的整数,然后将该整数转换为无意义的浮点数。
scanf
的引号(在方括号中带有一些格式和说明):
格式由零个或多个指令组成:
- 一个或多个空格字符;
- 一个普通的多字节字符(既不是%也不是空格字符)
- 或转换说明(如%d)。
因此格式字符串中的空格字符(例如,我建议的%c
中scanf("%d%d%d%d %c", ...
前面的空格)是伪指令,例如%d
...做什么?
由空格字符组成的指令通过读取输入直到第一个非空格字符(仍未读取)[...]来执行。
嗯,好的:它将跳过空格,并使下一个字符可用,这正是我们所需要的。 :-)。