[英]Pointer casting
What this code mean? 该代码是什么意思? i mean it's seem that we take the address of a variable and cast it to a (pointer type), after that we deferencing it, as we will know the value.
我的意思是,似乎我们采用了变量的地址并将其转换为(指针类型),之后我们对它进行了延迟,因为我们将知道该值。 Am I wrong?
我错了吗?
#include "stdio.h"
int main(void) {
int numI = 3;
float numF = * (float *)&numI;
printf("%f", numF);
numF = 3.0;
numI = * (int*)&numF;
printf("\n%d", numI);
return 0;
}
Consider these steps: 请考虑以下步骤:
numI
and numF
are 2 objects that happen to have the same size on your architecture, namely 4 bytes. numI
和numF
是2个对象,它们在您的体系结构上恰好具有相同的大小,即4个字节。 &numI
is an expression with type int *
and its value is the address of the object numI
. &numI
是类型为int *
的表达式,其值是对象numI
的地址。 (float *)&numI
is an expression of type float *
with the same value. (float *)&numI
是具有相同值的float *
类型的表达式。 Aking to telling the compiler, this address is that of a float
. float
地址 。 *(float *)&numI
produces a value of type float
that depends on the actual representation of int
for the value 3
. *(float *)&numI
引用此表达式*(float *)&numI
会生成一个float
类型的值,该值取决于值3
的int
实际表示形式。 For example, on the intel core processors (little endian, 32-bit, 2s complement) the bytes at address intI
would contain 03 00 00 00
. intI
处的字节将包含03 00 00 00
。 float
objects are represented in memory on the same processor using the IEEE-756 Standard: 03 00 00 00
represents the very small value 1.5 x 2 -148 , approximately 4.2039e-45 . float
对象使用IEEE-756标准在同一处理器上的内存中表示: 03 00 00 00
表示非常小的值1.5 x 2 -148 ,大约为4.2039e-45 。 printf
first converts it to type double
, with the same value and printf
converts the value to 0.000000
because the format %f
specifies only 6 decimal places and no exponent. printf
首先将其转换为double
,并使用相同的值,而printf
将该值转换为0.000000
因为格式%f
仅指定了6个小数位,并且没有指数。 In order to get a more precise conversion, you could use %g
which would produce 4.2039e-45
, or %a
which would produce the hexadecimal representation 0x1.8p-148
. %g
生成4.2039e-45
或%a
生成十六进制表示形式0x1.8p-148
。 float
value 3.0F
whose IEEE-756 representation is 00 00 40 40
is reinterpreted as an int
, producing the value 1077936128
. 00 00 40 40
的float
值3.0F
重新解释为int
,产生值1077936128
。 Here is a modified version of your program that makes it more explicit: 这是您的程序的修改后的版本,可以使它更加明确:
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
int main(void) {
int numI;
float numF;
unsigned char *p;
assert(sizeof numI == sizeof numF);
numI = 3;
p = (unsigned char *)&numI;
printf("int value %d is represented in memory as %02X %02X %02X %02X\n",
numI, p[0], p[1], p[2], p[3]);
//numF = *(float *)&numI;
memcpy(&numF, &numI, sizeof numF);
printf("reinterpreted as float with format %%f: %f\n", numF);
printf("reinterpreted as float with format %%g: %g\n", numF);
printf("reinterpreted as float with format %%a: %a\n", numF);
printf("numF exact value: %g * 2^-148\n", numF * pow(2.0, 148));
numF = 3.0;
p = (unsigned char *)&numF;
printf("float value %.1g is represented in memory as %02X %02X %02X %02X\n",
numF, p[0], p[1], p[2], p[3]);
//numI = *(int *)&numF;
memcpy(&numI, &numF, sizeof numI);
printf("reinterpreted as int with format %%d: %d\n", numI);
printf("reinterpreted as int with format %%#X: %#X\n", numI);
return 0;
}
Output: 输出:
int value 3 is represented in memory as 03 00 00 00
reinterpreted as float with format %f: 0.000000
reinterpreted as float with format %g: 4.2039e-45
reinterpreted as float with format %a: 0x1.8p-148
numF exact value: 1.5 * 2^-148
float value 3 is represented in memory as 00 00 40 40
reinterpreted as int with format %d: 1077936128
reinterpreted as int with format %#X: 0X40400000
Note however that: 但是请注意:
int
and float
are architecture specific. int
和float
类型的内存表示形式是体系结构特定的。 Some systems represent int
with big-endian byte order, some have padding bits and trap values, some vintage systems even used one's complement or sign+magnitude representations. int
,一些系统具有填充位和陷阱值,一些老式系统甚至使用补码或正负号表示。 The representations for float
can be even more exotic, although most current systems use IEEE-756 with the same byte ordering as integers. float
的表示形式可能更为奇特。 So your program has undefined behavior again, and at best produces implementation specific output. memcpy
, as shown in the modified code. memcpy
复制字节,如修改后的代码所示。 Modern compilers will produce very efficient code for this, expanding the memcpy
to a mere 2 instructions if not less. memcpy
扩展为仅2条指令(如果不是更少的话)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.