几十年前我做了一些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);
}
Run Code Online (Sandbox Code Playgroud)
输入
Enter age: 1
Enter age: 1
Enter age: 1
Enter age: -1
Run Code Online (Sandbox Code Playgroud)
产量
Number of 1 year olds = -1
Number of 2 and 3 year olds = 0
Number above 3 year olds = 0
Run Code Online (Sandbox Code Playgroud)
num_1_yr_olds值搞砸了.我期待一个3,我得到-1.无论输入如何,num_1_yr_olds的值都变为-1.
你的问题在于:
short int age = 0;
:
scanf ("%d", &age);
Run Code Online (Sandbox Code Playgroud)
您确实需要确保您的数据类型与您的格式字符串匹配.正确的格式说明的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 |
+-----------------------+
Run Code Online (Sandbox Code Playgroud)
所以,当你进入1
,age
成为1
和num_1_year_olds
成为0
.
每次你这样做的时候,它会增加num_1_year_olds
,因为age
是1
但将由覆盖scanf
你输入的下一次.
当你最终输入-1
(所有1位为二进制补码)时,age
变为-1
等等num_1_year_olds
.
然后,因为age
小于1,循环中断,并且值是你看到的:{-1, 0, 0}
.