【发布时间】:2017-06-29 19:13:50
【问题描述】:
这是我对这段代码的第二个问题。 此代码来自“Sams 自学 C 编程”第 7 版第 66 页上的修改脚本。 把书上的剧本抄下来后,我(只是一点点)修改了它,让它更有趣。
- 我添加了一些额外的常量和变量等,使其能够接受更大的输入/输出值。
- 因为输入/输出是“unsigned long int”类型,其范围为 0 - 2147483647,我将其设置为 LIMIT。
- 然后我在程序的最后添加了一个“else”来处理高于该值的所有输入。我只是想做一个实验,看看它是否会记录超出范围的值。
- 我第一次发布关于代码中的数学错误的问题,但我自己没有找到。已解决。
以下是一些示例输出:
[bad_cat@KittyLitter LearningCode]$ gcc SamsC.04.seconds.c
[bad_cat@KittyLitter LearningCode]$ ./a.out
Enter the number of seconds ( > 0, < 2147483647 ):
2147483646
2147483646 seconds is equal to 68 y 35 d, 3 h, 14 m, and 6 s
[bad_cat@KittyLitter LearningCode]$ ./a.out
Enter the number of seconds ( > 0, < 2147483647 ):
2147483647
2147483647 seconds is equal to [bad_cat@KittyLitter LearningCode]$ ./a.out
Enter the number of seconds ( > 0, < 2147483647 ):
2147483650
-2147483646 seconds is equal to error: -2147483646 is an excessive amount of seconds.
range for seconds must be between 0 and 2147483647!
If number of seconds exceeds 2147483647, then it is beyond range for type 'int'.
EXITING seconds program.
[bad_cat@KittyLitter LearningCode]$ ./a.out
Enter the number of seconds ( > 0, < 2147483647 ):
9876543210
1286608618 seconds is equal to 40 y 291 d, 7 h, 16 m, and 58 s
[bad_cat@KittyLitter LearningCode]$
代码如下:
/* Illustrates the modulus operator. */
/* inputs a number of seconds, and converts to hours, minutes, and seconds. */
// minute = 60 seconds : 60
// hour = 60 * 60 seconds : 3600
// day = 24 * 60 * 60 seconds : 86400
// year = 365 * 24 * 60 * 60 seconds : 31536000
#include <stdio.h> // from original script
/* Define constants */
#define SECS_PER_MIN 60 // from original script
#define MIN_PER_HOUR 60
#define HOURS_PER_DAY 24
#define DAYS_PER_YEAR 365
#define SECS_PER_YEAR 31536000
#define SECS_PER_HOUR 3600 // from original script
#define SECS_PER_DAY 86400
#define LIMIT 2147483647
unsigned seconds, minutes, hours, days, years, secs_remain, mins_remain, hours_remain, days_remain; // modified from original script
int main(void) // from original script
{
seconds = minutes = hours = days = years = secs_remain = mins_remain = hours_remain = days_remain = 0;
/* Input the number of seconds. */
printf( "Enter the number of seconds ( > 0, < %d ): \n", LIMIT ); // modified from original script
scanf( "%d", &seconds ); // from original script
years = seconds /SECS_PER_YEAR;
days = seconds / SECS_PER_DAY;
hours = seconds / SECS_PER_HOUR; // from original script
minutes = seconds / SECS_PER_MIN; // from original script
days_remain = days % DAYS_PER_YEAR;
hours_remain = hours % HOURS_PER_DAY;
mins_remain = minutes % MIN_PER_HOUR; // modified from original script
secs_remain = seconds % SECS_PER_MIN; // from original script
printf( "%d seconds is equal to ", seconds ); // from original script
if ( seconds < SECS_PER_HOUR )
{
printf( "%d m, and %d s\n", minutes, secs_remain );
return 0;
}
else if((seconds >= SECS_PER_HOUR ) && (seconds < SECS_PER_DAY ))
{
printf( "%d h, %d m, and %d s\n", hours, mins_remain, secs_remain ); // from original script
return 0; // from original script
}
else if((seconds >= SECS_PER_DAY ) && (seconds < SECS_PER_YEAR ))
{
printf( "%d d, %d h, %d m, and %d s\n", days, hours_remain, mins_remain, secs_remain );
return 0;
}
else if((seconds >= SECS_PER_YEAR ) && (seconds < LIMIT ))
{
printf( "%d y %d d, %d h, %d m, and %d s\n", years, days_remain, hours_remain, mins_remain, secs_remain );
return 0;
}
else if(seconds > LIMIT )
{
printf("error: %d is an excessive amount of seconds.\n", seconds);
printf("range for seconds must be between 0 and %d!\n", LIMIT );
printf("If number of seconds exceeds %d, then it is beyond range for type 'int'.\n", LIMIT );
printf("EXITING seconds program. \n");
return 1;
}
}
谢谢,我已将所有 "%d" 更改为 "%u" 和 Limit。
我也把它放在一起以供将来参考:
#include <stdio.h>
#include <limits.h>
int main(void)
{
printf("\n");
printf("The number of bits in a byte =\t\t\t\t %d\n", CHAR_BIT);
printf("The maximum number of bytes in a multi-byte character =\t %d\n", MB_LEN_MAX);
printf("The minimum value of SIGNED CHAR =\t\t\t %d\n", SCHAR_MIN);
printf("The maximum value of SIGNED CHAR =\t\t\t %d\n", SCHAR_MAX);
printf("The maximum value of UNSIGNED CHAR =\t\t\t %d\n", UCHAR_MAX);
printf("The minimum value of SHORT INT =\t\t\t %d\n", SHRT_MIN);
printf("The maximum value of SHORT INT =\t\t\t %d\n", SHRT_MAX);
printf("The maximum value for an UNSIGNED SHORT INT =\t\t %u\n", USHRT_MAX);
printf("The minimum value of INT =\t\t\t\t %d\n", INT_MIN);
printf("The maximum value of INT =\t\t\t\t %d\n", INT_MAX);
printf("The maximum value for an UNSIGNED INT =\t\t\t %u\n", UINT_MAX);
printf("The minimum value of CHAR =\t\t\t\t %d\n", CHAR_MIN);
printf("The maximum value of CHAR =\t\t\t\t %d\n", CHAR_MAX);
printf("The minimum value of LONG =\t\t\t\t %ld\n", LONG_MIN);
printf("The maximum value of LONG =\t\t\t\t %ld\n", LONG_MAX);
printf("The maximum value for an UNSIGNED LONG INT =\t\t %Lu\n", ULONG_MAX);
printf("\n");
return(0);
}
【问题讨论】:
-
问题是?
-
unsigned long int 的范围不是这样,除非你有一个非常奇怪的 31 位架构。
-
您使用的是 64 位系统吗?然后 GCC 将为
long使用 64 位。 -
为什么不阅读
scanf的手册页并注意返回值以及 %d 的含义 -
顺便说一下,我没有看到您在显示的代码中的任何地方使用
unsigned long?您的所有变量都是unsigned类型,这意味着unsigned int,自过去 30 年左右以来,在所有现代平台上都是 32 位。