我有以下代码:
short num_short = 1;
int possible_new_short = 1;
valid = 1;
while (valid) {
possible_new_short = num_short * 10;
printf("----\n");
printf("Num Short: %d\n", num_short);
printf("Possible New Short: %d\n", possible_new_short);
if (possible_new_short % 10 == 0) {
num_short = possible_new_short;
printf("New! %d\n", num_short);
} else {
valid = 0;
}
if (num_short == 0) {
valid = 0;
}
}
printf("num_short: %d\n", num_short);
输出如下:
----
Num Short: 1
Possible New Short: 10
New! 10
----
Num Short: 10
Possible New Short: 100
New! 100
----
Num Short: 100
Possible New Short: 1000
New! 1000
----
Num Short: 1000
Possible New Short: 10000
New! 10000
----
Num Short: 10000
Possible New Short: 100000
New! -31072
----
正如您所看到的,possible_new_short
的值为100000
,但在重新分配给num_short
时,它会转到-31072
。为什么会这样?
我对C完全陌生,我的猜测是num_short
变量溢出。由于num_short
和possible_new_short
存储在不同的内存插槽中,因此可能会溢出,而且可能会出现问题?
有哪些最佳做法可以防范这种情况?
答案 0 :(得分:1)
您的猜测是正确的,num_short
的类型为short
,在今天的大多数机器中通常为16位。
16位有符号整数最多可以保存2 15 - 1,即32767
。最后一个值100000
溢出。
possible_new_short
不会溢出,因为其类型为int
。通常,考虑变量保存的最大可能值,并相应地定义其类型。例如,您可以改为使用long
甚至long long
。
答案 1 :(得分:1)
short的范围为-32,768到32,767。因此,当你尝试为num_short分配100000时,它会溢出并导致未定义的行为。但是尽管如此可能是int,它的范围是-2,147,483,648到2,147,483,647并且可以存储值为100000.So使你的num_short成为合适的类型。
答案 2 :(得分:1)
以下是发生的事情。我相信你会得到一些编译器警告。不要忽视它们。你的下一行
if (possible_new_short % 10 == 0) {
num_short = possible_new_short;
在这里,您将num_short分配给一个值,该值大于possible_new_short
变为1000000时最大短值可以保持的值,它的十六进制值为0xFFFF8640
。当您将其分配给较短的高阶时,将忽略2个字节(FFFF
),值变为0x86A0
,如果使用%d
打印,则其值为-31072。
所以你的任务是个问题。
答案 3 :(得分:1)
C提供各种数据类型。我们可以根据我们的要求从提供的类型中进行选择。 short的范围总是小于int,两者都可以容纳的值的范围取决于环境。在上面的代码段中,您尝试将值 100000 分配给short类型。由于此值caanot存储在short变量中,因此它会溢出变量,并且它会从该范围的另一端给出值。这可以理解为
char的大小为1个字节,因此 signed char 的值范围为 -127到+127 现在,如果指定 char a = 127 < / strong>即可。它工作正常,但尝试分配 char a = 128 。当你打印a的值时,你会得到 -127 ,这是来自该范围的另一面。
类似地,对于 unsigned char ,值的范围将为 0到255 。因此,当您尝试分配大于范围的值时,请说 unsigned char a = 256 。您将从范围的另一侧获得值。当您打印a的值时,它将为您提供零
这可以通过数字的二进制表示来理解 我们将考虑 unsigned char 因为char是1个字节,即8位,所以当我们尝试分配256时,这就是256的二进制表示是 0000000100000000 最低有效位都是0,最终分配给 a 因为它只能容纳8位,这就是为什么当我们为a分配256时得到0的原因。在你的情况下也会发生同样的问题。
要使上面的代码段正常工作,请将变量num_short声明为 int
答案 4 :(得分:0)
short
(在您的机器上)是带符号的16位(2字节)类型。
如果指定100000
,需要17位:1 10000110 10100000
(按字节分组),最高位将被截断。
结果是,您的possible_new_short
结尾为10000110 10100000
,即-31072
。
为了防止溢出,您可以使用INT16_MAX
(和INT-16_MIN
)进行检查。