#include <stdio.h>
int main(void) {
short int age = 0;
short int num_1_yr_olds = 0;
short int num_2_and_3_yr_olds = 0;
short int num_above_3_yr_olds = 0;
while(1) {
printf ("Enter age: ");
scanf ("%d", &age);
if (age < 1) {
break;
}
switch (age) {
case 1:
++num_1_yr_olds;
break;
case 2:
case 3:
++num_2_and_3_yr_olds;
break;
default:
++num_above_3_yr_olds;
break;
}
}
printf ("Number of 1 year olds = %d\n", num_1_yr_olds);
printf ("Number of 2 and 3 year olds = %d\n", num_2_and_3_yr_olds);
printf ("Number above 3 year olds = %d\n", num_above_3_yr_olds);
}
输入
Enter age: 1
Enter age: 1
Enter age: 1
Enter age: -1
输出
Number of 1 year olds = -1
Number of 2 and 3 year olds = 0
Number above 3 year olds = 0
num_1_yr_olds值搞砸了。我期待一个3,我得到-1。无论输入如何,num_1_yr_olds的值都变为-1。
答案 0 :(得分:9)
你的问题在于:
short int age = 0;
:
scanf ("%d", &age);
您确实需要确保您的数据类型与您的格式字符串匹配。 short int
的正确格式说明符为%hd
,而不是%d
。
有些编译器会检查这个并警告你。
可能发生的事情是数据和格式字符串的错位导致short int
成为“错误”值,因此计数被搞砸了。
更深入地说,对于像x86这样的小端结构,将int
扫描到short
可能会将最不重要的一半放入age
和最重要的一半进入num_1_year_olds
(如果它与内存中的age
相邻)。
从图形上看,可能更清楚地想到这样:
shorts in memory
+-----------------------+
What scanf("%hd") =< | age | \
will write to. +-----------------------+ = What scanf("%d")
| num_1_year_olds | / will write to.
+-----------------------+
| num_2_and_3_year_olds |
+-----------------------+
| num_above_3_year_olds |
+-----------------------+
因此,当您输入1
时,age
变为1
而num_1_year_olds
变为0
。
每次执行此操作时,num_1_year_olds
都会增加age
,因为1
为scanf
,但下次您输入时会被-1
覆盖。
当您最终输入age
(所有1位为二进制补码)时,-1
变为num_1_year_olds
,age
也是如此。
然后,由于{-1, 0, 0}
小于1,因此循环中断,并且您看到的值为{{1}}。
答案 1 :(得分:2)
尝试
scanf ("%hd", &age);
因为age是short int类型。