在C中,无符号和有符号字符指针之间的转换何时变得不安全?

如果我在clangVisual Studio中都这样做:

  unsigned char *a = 0; char * b = 0; char x = '3'; a = & x; b = (unsigned char*) a; 

我收到警告,我正在尝试在有符号和无符号字符指针之间进行转换,但代码确实有效。 虽然编译器说这是有原因的。 你能指出一个可能变成问题的情况吗?

为了使它变得非常简单,因为char表示:

  • 单个字符( char ,如果签名则无关紧要)。 当您指定像'A'这样的字符时,您正在做的是在该存储位置写入ASCII码(65)。
  • 字符串(用作char缓冲区的数组或指针)。
  • 一个八位 (带或不带符号)。

然后当你将一个有符号的字节(如-1)转换为无符号字节时,你会丢失信息(至少是符号,但可能也是数字),这就是你得到警告的原因:

 signed char a = -1; unsigned char b = (unsigned char)a; if ((int)b == -1) ; // No! Now b is 255! 

如果您的系统不代表带有2的补码的负数,则值可能不是255而是1,在该示例中它并不重要(我从未使用过任何类似的系统,但它们存在),因为该概念是签名的/未签名的转换可能会丢弃信息 。 如果由于显式强制转换或通过指针强制转换而发生这种情况并不重要:位将代表其他东西(结果将根据实现,环境和实际值而变化)。

请注意,对于C标准charsigned charunsigned char是正式不同的类型。 您不会关心(并且VS将根据编译器选项将char默认为signedunsigned但这不可移植)并且您可能需要强制转换。

您的代码是正确的(任何类型都可以通过unsigned char别名)。 此外,在2的补码系统上,此别名与值转换的结果相同。

反向操作; 别名unsigned char by char只是在具有普通char陷阱表示的深奥系统上的一个问题。

我不知道有任何这样的系统存在,尽管C标准规定了它们的存在。 不幸的是,由于这种可能性需要演员,这比有用的恕我直言更烦人。

unsigned charunsigned char别名与我所知道的每个现代系统的值转换相同(技术实现定义,但每个人都实现了值转换保留相同的表示)。

NB。 术语的定义,例如unsigned char x = 250;

  • 别名 char y = *(char *)&x;
  • 转换 char y = x;

char类型可以是签名的或不签名的,具体取决于平台。 使用将char类型转换为unsigned或signed char而编写的代码可能在一个平台内正常工作,但如果数据是跨操作系统ETC传输的,则不行。 看到这个url:

http://www.trilithium.com/johan/2005/01/char-types/

因为你可能会失去一些价值 – 看看这个:

 unsigned char *a = 0; char b = -3; a = &b; printf("%d", *a); 

结果: 253

让我解释一下。 只看范围:

unsigned char:从0到255
signed char:从-128到127

编辑:抱歉错误,今天太热了;)