在C中,无符号和有符号字符指针之间的转换何时变得不安全?
如果我在在C中,无符号和有符号字符指针之间的转换何时变得不安全?,c,visual-studio-2010,pointers,clang,C,Visual Studio 2010,Pointers,Clang,如果我在clang和visualstudio中都这样做: unsigned char *a = 0; char * b = 0; char x = '3'; a = & x; b = (unsigned char*) a; 我得到警告,我正试图在有符号和无符号字符指针之间转换,但代码确实有效。尽管编译器这么说是有原因的。你能指出一种情况,在这种情况下,这可能会变成一个问题吗?因为你可能会丢失一些值-看看这个: unsigned char *a = 0; cha
clang
和visualstudio
中都这样做:
unsigned char *a = 0;
char * b = 0;
char x = '3';
a = & x;
b = (unsigned char*) a;
我得到警告,我正试图在有符号和无符号字符指针之间转换,但代码确实有效。尽管编译器这么说是有原因的。你能指出一种情况,在这种情况下,这可能会变成一个问题吗?因为你可能会丢失一些值-看看这个:
unsigned char *a = 0;
char b = -3;
a = &b;
printf("%d", *a);
结果:253
让我解释一下。只要看看范围:
未签名字符:从0到255签名字符:从-128到127
编辑:抱歉弄错了,今天太热了;) 非常简单,因为
char
表示:
- 单个字符(
,无论是否签名)。当您指定一个字符,如char
时,您要做的是在该内存位置写入一个ASCII码(65)'a'
- 字符串(当用作数组或指向
缓冲区的指针时)char
- 八位数字(带或不带符号)
signed char a = -1;
unsigned char b = (unsigned char)a;
if ((int)b == -1)
; // No! Now b is 255!
如果您的系统不使用2的补码表示负数,则值可能不是255而是1,在该示例中,这并不重要(我从未使用过任何类似的系统,但它们是存在的),因为这个概念是有符号/无符号转换,可能会丢弃信息。无论这种情况是由于显式转换还是通过指针转换而发生:位将表示其他内容(结果将根据实现、环境和实际值而改变)
注意,对于C标准的char
,signed char
和unsigned char
是形式上不同的类型。您不必在意(根据编译器选项,VS会将char
默认为signed
或unsigned
,但这不是可移植的),您可能需要强制转换。您的代码是正确的(任何类型都可以用unsigned char
作为别名)。此外,在2的补码系统上,此别名与值转换的结果相同
反向操作;通过char
对unsigned char
进行混叠,这仅仅是对普通char
具有陷阱表示的深奥系统的一个问题
我不知道有任何这样的系统曾经存在过,尽管C标准规定了它们的存在。不幸的是,由于这种可能性,需要强制转换,这比有用的IMHO更烦人
char
对unsigned char
的别名与我所知的每个现代系统上的值转换是相同的(技术上定义了实现,但每个人都实现了值转换保留相同的表示)
注意。术语定义,例如无符号字符x=250代码>:
- 别名
chary=*(char*)&x代码>
- 转换
chary=x代码>
字符类型可以是有符号的,也可以是无符号的,具体取决于平台。通过将字符类型强制转换为无符号或有符号字符而编写的代码可能在一个平台内正常工作,但如果数据跨操作系统传输,则可能无法正常工作。请参阅以下URL:
因此,如果我唯一分配无符号字符和有符号字符的是字符串,那么差异就无关紧要了?是的,但不要忘记char、有符号字符和无符号字符是形式上不同的类型(如果将它们用作库函数的输入,则很重要)。最后,这并不重要,但你可能需要施法。(int)b==-1
产生true。@self。正如我们所期望的那样,它会产生false
。如果b
为无符号字符
,则原始负值已丢失。你能解释一下在你可能使用的任何编译器中如何255==-1
吗?@AdrianoRepetti看起来我发现了一个编译器错误:9即使使用了固定的代码,结果也是正确的:253int I;无符号u=0;对于(i=10;i>=u;--i){put(“永远这样做”);}