使用指针类型转换时值发生莫名其妙的变化

时间:2018-12-31 13:10:53

标签: c pointers typecasting-operator

 #include <stdio.h>
 int main() { 

   int num=1;
   char *b;
   b=(char*)&num;
   *(++b)=2;
   printf("%d\n",num);

   return 0; 
}

编译此代码时,我遇到“ 513”作为输出。 当我在该行上使用注释行时:

*(++b)=2;

输出转换为“ 1”。

为什么我会遇到“ 513”作为输出?

为什么使用我暗示的注释行时输出会发生变化?

4 个答案:

答案 0 :(得分:1)

假设int是32位且系统上的字节序很少,num的表示形式为0x00000001,在内存中看起来像这样:

-----------------
| 1 | 0 | 0 | 0 |
-----------------

然后将b指向num

  b
  |
  v
-----------------
| 1 | 0 | 0 | 0 |
-----------------

然后您执行*(++b)=2;,它递增b,取消引用递增的指针,然后将2写入该位置。所以你现在有了。

      b
      |
      v
-----------------
| 1 | 2 | 0 | 0 |
-----------------

因此,num的表示形式是0x00000201`,即十进制的513。

答案 1 :(得分:0)

看来,在您的计算机上,字符是字节大小的。这就是为什么您看到这种完全正常的行为。

您的num变量在内存中看起来像这样。

0x00000001

您获取地址,将其视为char *,然后将第二个char设置为2,这样您的num就变成了。

0x00000201

当您将其转换回十进制时,它会正确输出513。

答案 2 :(得分:0)

int num=1;

32 bit系统中的表示方式如下

     0x103      0x102       0x101       0x100  (let's assume base address of num 0x100)
  -----------------------------------------------
 | 0000 0000 | 0000 0000 | 0000 0000 | 0000 0001 |
  -----------------------------------------------
                                                num
MSB                                          <--LSB

还有这里

char *b; /* char pointer i.e at a time points to 1 byte */
b=(char*)&num; /* b points to &num i.e 0x100 in above diagram */

看起来像

    0x103      0x102       0x101       0x100  
  -----------------------------------------------
 | 0000 0000 | 0000 0000 | 0000 0000 | 0000 0001 |
  -----------------------------------------------
                                                num
                                                 b <-- b points here 

现在什么时候

*(++b)=2;

开始执行,首先发生++b,这意味着char指针b递增了一个字节,即它指向0x101的位置,然后指向由{ 0x101。看起来像

2

现在,当您打印 0x103 0x102 0x101 0x100 ----------------------------------------------- | 0000 0000 | 0000 0000 | 0000 0010 | 0000 0001 | ----------------------------------------------- | num b <-- b points to 0x101 时,它会打印num的{​​{1}}。我希望它能消除您的疑问。

答案 3 :(得分:0)

  

编译此代码时,我遇到“ 513”作为输出。

由于以下语句,您得到此输出:

*(++b)=2;

最初,b指向num。语句*(++b)=2将首先递增指针b并指向下一个字节,然后对其进行解引用并分配2
假设您平台上的int位为32,则:

initially
num = 1

00000000 00000000 00000000 00000001


num after this statement
*(++b)=2;

00000000 00000000 00000010 00000001

which is the binary representation of `513`.
  

当我在该行上使用注释行时:*(++b)=2;输出将转换为“ 1”。

当然,您已经用num初始化了1,并且在打印num时还没有进行任何更改。