如果我在 clang
和 Visual Studio
中执行此操作:
unsigned char *a = 0;
char * b = 0;
char x = '3';
a = & x;
b = (unsigned char*) a;
我收到警告,说我正在尝试在有符号和无符号字符指针之间进行转换,但代码确实有效。尽管编译器这么说是有原因的。您能指出在什么情况下这可能会成为问题吗?
最佳答案
为了使其变得非常简单,因为 char
代表:
- 单个字符(
char
,是否有符号并不重要)。当您分配像'A'
这样的字符时,您所做的就是在该内存位置写入 A ASCII 代码 (65)。 - 字符串(当用作数组或指向
char
缓冲区的指针时)。 - 一个八位数字(带或不带符号)。
然后,当您将 -1 这样的有符号字节转换为无符号字节时,您将丢失信息(至少是符号,但也可能是数字),这就是您收到警告的原因:
signed char a = -1;
unsigned char b = (unsigned char)a;
if ((int)b == -1)
; // No! Now b is 255!
值可能不是 255,而是 1,如果您的系统不表示带有 2 补码的负数,在该示例中,这并不重要(我从未使用过这样的系统,但是它们存在),因为这个概念是有符号/无符号转换可能会丢弃信息。无论是由于显式强制转换还是通过指针强制转换而发生这种情况都没关系:位将代表其他内容(并且结果将根据实现、环境和实际值而变化)。
请注意,对于 C 标准,char
、signed char
和 unsigned char
是形式上不同的类型。你不会在意(VS会根据编译器选项将char
默认为signed
或unsigned
,但这不是可移植的)可能需要类型转换。
关于c - 在 C 中,无符号和有符号字符指针之间的转换何时变得不安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24059367/