将指针强制转换为char指针会导致C中的数据丢失?

时间:2011-03-06 03:50:22

标签: c pointers

我有以下代码:

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
  int n = 260; 
  int *p = &n;
  char *pp = (char*)p;
  *pp = 0;

  printf("n = %d\n", n);
  system("PAUSE");  
  return 0;
}

该程序的输出放置为n = 256。 我可能理解为什么,但我不确定。 请问有人能给我一个明确的解释吗?

非常感谢。

7 个答案:

答案 0 :(得分:11)

int 260(= 256 * 1 + 4)在内存中看起来像这样 - 请注意,这取决于机器的endianness - 这也适用于32位( 4字节)int

0x04 0x01 0x00 0x00

通过使用char指针,指向第一个字节并将其更改为0x00,这会将int更改为256(= 256 * 1 + 0)。

答案 1 :(得分:3)

你显然是在使用小端机器。发生的事情是你从一个占用至少两个字节的int开始。值260是256 + 4。 256进入第二个字节,第4个进入第一个字节。当你向第一个字节写0时,你只剩下第二个字节中的256个。

答案 2 :(得分:1)

我明白改变价值究竟发生了什么:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
  int n = 260; 
  int *p = &n;
  char *pp = (char*)p;
  *pp = 20;

    printf("pp = %d\n", (int)*pp);
  printf("n = %d\n", (int)n);
  system("PAUSE");  
  return 0;
}

输出值是 20 和 276

所以基本上问题不在于你有数据丢失,是char指针只指向int的第一个字节,所以它只改变了,其他字节没有改变,这就是为什么那些奇怪的值(如果你在INTEL处理器上,第一个字节是最不重要的,这就是你改变数字“最小”部分的原因

答案 3 :(得分:1)

在C中,指针根据与指针关联的类型引用字节块。因此,在您的情况下,整数指针指的是大小为4个字节的块,而char只有一个字节长。当您将char设置为0时,它只会更改整数值的第一个字节,但由于数字在现代机器的内存中的存储方式(实际上与编写它的方式相反),您将覆盖最低有效字节(这是4)你剩下w / 256作为值

答案 4 :(得分:0)

你的问题是作业 * pp = 0; 您正在取消引用指向n的pp,并更改n。 但是,pp是一个char指针,所以它不会改变所有n 这是一个int。这导致其他答案中的二元并发症。

答案 5 :(得分:0)

就C语言而言,您正在做的描述是修改int变量n的表示。在C中,所有类型都有一个“表示”作为一个或多个字节(unsigned char),通过转换指向char *unsigned char *的指针来访问底层表示是合法的 - 后者如果我在这里进入这些原因会更加不必要地使事情复杂化,这样做会更好。

正如schnaader回答的那样,在一个小端上,二十三补充了32位int的实现,260的表示是:

0x04 0x01 0x00 0x00

并用0覆盖第一个字节,产生:

0x00 0x01 0x00 0x00

是这种实现的256的表示。

C允许具有填充位和陷阱表示的实现(如果访问它们会引发信号/中止您的程序),因此通常以这种方式覆盖部分但不是全部int是不安全的去做。尽管如此,它确实可以在大多数真实世界的机器上运行,如果您使用类型uint32_t,它将保证可以工作(尽管这些位的排序仍然依赖于实现)。

答案 6 :(得分:0)

考虑32位系统, 256将以这样的方式表示。

00000000 (Byte-3)   00000000 (Byte-2)    00000001(Byte-1)     00000100(Byte-0)

现在,当p被类型转换为char指针时,指针上的标签会发生变化,但内存内容不会变化。这意味着较早的p可以访问4个字节,因为它是一个整数指针,但现在它只能访问1个字节,因为它是一个char指针。因此,只有LSB变为零,而不是所有4个字节。

它变成了

00000000 (Byte-3)   00000000 (Byte-2)    00000001(Byte-1)     00000000(Byte-0)

因此,o / p为256