变量(短)在复制/分配时更改值

时间:2015-06-04 04:46:55

标签: c

我有以下代码:

  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_shortpossible_new_short存储在不同的内存插槽中,因此可能会溢出,而且可能会出现问题?

有哪些最佳做法可以防范这种情况?

5 个答案:

答案 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)进行检查。