繁体   English   中英

C中的指针与类型转换

[英]Pointers in C with typecasting

#include<stdio.h> 
int main() 
{ 
    int a; 
    char *x; 
    x = (char *) &a; 
    a = 512; 
    x[0] = 1; 
    x[1] = 2; 
    printf("%d\n",a); 
    return 0; 
}

我无法掌握输出是如何513甚至机器依赖的事实? 我可以感觉到类型转换正在发挥重要作用,但幕后发生了什么,有人可以帮助我想象这个问题吗?

int a作为4个字节存储在内存中。 数字512在您的机器上表示为:

0 2 0 0

分配给x[0]x[1] ,它将其更改为:

1 2 0 0

这是513

这与机器有关,因为C语言没有指定多字节数字中的字节顺序。

为简化假设以下内容:

  • int的大小是4(以字节为单位)
  • 任何指针类型的大小为8
  • char的大小是1个字节

在第3行x中引用a作为char,这意味着x认为他指向了一个char(他不知道a实际上是一个int。

第4行是为了让你感到困惑。 别。

第5行 - 因为x认为他指向一个字符x [0] = 1只改变a的第一个字节(因为他认为他是一个字符)

第6行 - 再一次,x改变了a的第二个字节。

请注意,第5行和第6行中的值位于第4行的值之上.a的值现在为0 ... 0000 0010 0000 0001(513)。

现在当我们打印一个int作为int时,所有4个字节都将被视为预期。

我无法理解输出如何是513甚至是机器依赖的事实

输出是实现定义的。 它取决于CPU对整数解释的字节顺序 ,通常称为字节序

我可以感觉到类型转换正在发挥重要作用

代码重新解释的值a ,这是一个int ,作为字节数组。 它使用两个初始字节,保证可以工作,因为int大小至少为两个字节。

有人可以帮助我想象这个问题吗?

int由多个字节组成。 它们可以作为一个表示整数的单元来寻址,但它们也可以作为字节集合进行寻址。 int的值取决于您设置的字节数,以及CPU对整数的解释中这些字节的顺序。

看起来你的系统将最低有效字节存储在最低地址,因此将12存储在偏移0和1的结果产生这种布局:

Byte 0 Byte 1 Byte 2 Byte 3
------ ------ ------ ------
     1      2      0      0

整数值可以如下计算:

1 + 2*256 + 0*65536 + 0*16777216

通过取x (它是一个char * )并将其指向a的地址(即int ,可以使用x来修改表示a的各个字节。

您看到的输出表明int以little-endian格式存储,这意味着最不重要的字节首先出现。 但是,如果您在另一个系统上运行此代码(例如,大型enidan的Sun SPARC计算机),则可能会发生这种情况。

首先将a设置为512.在十六进制中,即0x200 因此,假设以小端格式表示32位int a的内存布局如下:

-----------------------------
| 0x00 | 0x02 | 0x00 | 0x00 |
-----------------------------

接下来将x[0]设置为1,这将更新a表示中的第一个字节(在这种情况下保持不变):

-----------------------------
| 0x01 | 0x02 | 0x00 | 0x00 |
-----------------------------

然后将x[1]设置为2,这将更新a表示中的第二个字节:

-----------------------------
| 0x01 | 0x02 | 0x00 | 0x00 |
-----------------------------

现在a的值为0x201,十进制为513。

除了之前的答案之外,让我试着为你解决这个问题:

#include<stdio.h> 
int main() 
{ 
    int a;            //declares an integer called a
    char *x;          //declares a pointer to a character called x
    x = (char *) &a;  //points x to the first byte of a
    a = 512;          //writes 512 to the int variable
    x[0] = 1;         //writes 1 to the first byte
    x[1] = 2;         //writes 2 to the second byte
    printf("%d\n",a); //prints the integer
    return 0; 
}

请注意,我写了第一个字节和第二个字节。 根据平台的字节顺序和整数的大小,您可能得不到相同的结果。

让我们看一下32位4字节大小的内存:

小端系统

first byte | second byte | third byte | forth byte
0x00           0x02        0x00         0x00

现在为第一个字节分配1,为第二个字节分配2,这给我们留下了:

first byte | second byte | third byte | forth byte
0x01           0x02        0x00         0x00

请注意,第一个字节更改为0x01而第二个字节已经是0x02 内存中的这个新数字相当于小端系统上的513

大端系统

让我们看一下如果你在一个大端平台上尝试这个会发生什么:

first byte | second byte | third byte | forth byte
0x00           0x00        0x02         0x00

这次将1分配给第一个字节,将2分配给第二个字节给我们留下:

first byte | second byte | third byte | forth byte
0x01           0x02        0x02         0x00

相当于16,908,800整数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM