几十年前我做过一些 C 编程。我正在尝试重新学习这门语言。我写了这个。我得到了意想不到的东西。当我将“short int”更改为“int”时,它似乎起作用了。任何人都可以查看我的代码以查看它是否有任何问题或者这是编译器问题。我在 Linux 上使用 gcc。
#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。
最佳答案
你的问题出在这里:
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
覆盖code> 下次你得到输入时。
当您最终输入 -1
(二进制补码中的所有 1 位)时,age
变为 -1
,num_1_year_olds 也是如此
。
然后,因为 age
小于一,循环中断,值就是您所看到的:{-1, 0, 0}
。
关于c - 我编码不正确吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12559164/