将指向整数的指针强制转换为指向char的指针时会发生什么?

int i=40; char *p; p=(char *)&i;//What actually happens here? printf("%d",*p); 

什么是输出? 请帮忙!

 p=(char *)&i;//What actually happens here? 

它接受i的地址并将其转换为char指针。 所以*p的值现在是i的第一个字节。 这个价值是什么,取决于平台。

让我们首先看一下ip的内容将如何在内存中布局(假设是big-endian顺序):

项目地址0x00 0x01 0x02 0x03
 ---- ------- ----------------------
    i 0x08000000 0x00 0x00 0x00 0x28
    p 0x08000004 0x ??  0X?  0X?  0X?

由于p被声明为自动变量,因此它没有初始化为任何东西,并且包含由0x??表示的随机位模式。 。

在线

 p = (char *)&i; 

表达式&i求值为i或0x08000000的地址,其类型是pointer to intint * pointer to int 。 强制转换将类型从int *转换为char * ,结果分配给p

以下是分配后内存中的内容:

项目地址0x00 0x01 0x02 0x03
 ---- ------- ----------------------
    i 0x08000000 0x00 0x00 0x00 0x28
    p 0x08000004 0x08 0x00 0x00 0x00

所以p的值现在是i地址 。 在线

 printf("%d", *p); 

表达式*p的类型是char ,它的值是存储在地址0x08000000中的值,在这种特殊情况下为0.因为printf是一个可变函数,所以*p的值从char类型提升为char类型。

因此对于这种特殊情况,输出为“0”。 如果订单是little-endian,那么地图就会像

项目地址0x03 0x02 0x01 0x00
 ---- ------- ----------------------
    i 0x08000000 0x00 0x00 0x00 0x28
    p 0x08000004 0x08 0x00 0x00 0x00

输出为“40”。

请注意,整个示例假设整数和字符指针具有相同的大小和布局; 这并不能保证在任何地方都是真实的(参见在线C标准(n1256草案) ,第6.2.5节,第27段),所以你不能按照你期望的方式依赖这个工作(假设我认为这是正确的) intchar不是标准定义的兼容类型,但我可能错了)。 一般来说,打字是不安全的。

这个给你

int i = 40; //为整数i分配内存并为其赋值40

 char *p = (char*)&i; 

所以在这里你要定义一个指针变量并在将其转换为char*之后为其分配i的地址

假设i被分配在1021 address所以p将具有该字节的限制为1字节,因此它应该first 8 bit from the representation of 40;保持first 8 bit from the representation of 40;

因为40已经覆盖了2字节的前8位,它将保持40当量的等效数,但是当你用%d打印它时,它会打印40 ;

这取决于。 在Windows上,输出将是40,但这只是因为很多巧合:

首先,printf没有(不能)检查其参数的类型,因此它在格式字符串中看到%d,它假定给定的参数是int。 虽然* p只是一个char,但结果会被提升为int(就像函数原型中未指定的每个参数一样)。

其次,p将指向变量i占用的内存,但由于它是一个char指针,因此它只占用i的内存中的一个字节。 由于Windows / Intel使用Least-Significant-Byte第一个约定,40将被存储为字节模式“40 0 0 0”,因此,因为* p取第一个字节(char),结果将是40.如果我将拥有值256或更大,结果将是不正确的。

当int指针被类型化为char时会发生什么? 还有另一个问题标记为重复,我试着解释一下。

 $ cat ac #include  int main(){ int a; char *x; x = (char *) &a; a=512; x[0]=1; x[1]=2; printf("%d\n",a); return 0; } 

编译并运行:

 $ gcc ac && ./a.out 513 

为什么是513? 我们可以使用gdb来查看根本原因。

 $ gcc ac -g && gdb ./a.out (gdb) list 1 #include  2 3 int main(){ 4 int a; 5 char *x; 6 x = (char *) &a; 7 a=512; 8 x[0]=1; 9 x[1]=2; 10 printf("%d\n",a); 

在交流的第8行设置一个断点,然后运行

 (gdb) b ac:8 Breakpoint 1 at 0x40113d: file ac, line 8. (gdb) run 

程序停止在断点处,打印变量a的内存地址。

 (gdb) p &a $2 = (int *) 0x7fffffffd9d4 (gdb) px $3 = 0x7fffffffd9d4 "" 

变量a的内存地址是0x7fffffffd9d4,变量x的值是相同的。

在显示内存内容之前,让我们了解512格式的hex格式,它是:

 00 00 02 00 

和x86是小端,所以在内存中它应该是:

 [higher address] 00 02 00 00 [lower address] 

让我们展示真实的记忆,就像我们想象的一样。

 (gdb) x/4xb 0x7fffffffd9d4 0x7fffffffd9d4: 0x00 0x02 0x00 0x00 

然后,显示x [0]和x [1]的内存地址,并将内存内容转换为实际值,应该不难理解为什么打印出513。

 (gdb) p &x[0] $4 = 0x7fffffffd9d4 "" (gdb) p &x[1] $5 = 0x7fffffffd9d5 "\002"