9

我看到了一段有效的 C 代码,我尝试将其编译为 C++,但出现了一个我无法理解的错误。

char* t;
signed char* v = t;

char*错误:从到的无效转换signed char*

根据我所学到的,charsigned char语义上是相同的,但编译器仍然认为是不同的。

我知道错误是由这两种类型之间的差异引起的,我的问题是:为什么存在这种差异?

据我所知char,它要么作为 a 要么作为 a 实现,signed char因此unsigned char它应该与其中一个或另一个相同。


我咨询了这个问题,它没有回答我想知道的问题。

4

3 回答 3

11

其实我终于找到了规范部分谈论这个:

3.9.1 基本类型

  1. 声明为字符 (char) 的对象应足够大以存储实现的基本字符集的任何成员。如果该集合中的字符存储在字符对象中,则该字符对象的整数值等于该字符的单个字符文字形式的值。char 对象是否可以保存负值是实现定义的。字符可以显式声明为无符号或有符号。普通字符、有符号字符和无符号字符是三种不同的类型。char、signed char 和 unsigned char 占用相同的存储量并具有相同的对齐要求(3.11);也就是说,它们具有相同的对象表示。对于字符类型,对象表示的所有位都参与值表示。对于无符号字符类型,值表示的所有可能的位模式都表示数字。这些要求不适用于其他类型。在任何特定实现中,普通 char 对象可以采用与带符号字符或无符号字符相同的值;哪一个是实现定义的。
于 2013-10-18T08:08:26.803 回答
0

根据我所学到的,charsigned char语义上是相同的,但仍然 > 被编译器认为是不同的。

不。char在语义上与 不同signed char

与其他整数类型(整数、长整数、短整数等)相比,不能保证没有 a 的 charsignedunsignedsigned. 这是实现定义的。一些架构将其定义为signed,其他架构定义为unsigned 现实世界中的

因此,使用char,如果签名很重要,您确实需要指定您想要的。

我的建议是,如果您正在进行字符操作等,或者使用使用charor的 api 调用char *,则使用char. 如果您只想要一个 8 位整数值,请确保您指定signed charor unsigned char,这样在几年内当您移植到不同的架构时,您就不会陷入困境。

或者更好的是,使用uint8_torint8_t表示 8 位整数。

编辑:根据您自己的回答:

这些要求不适用于其他类型。在任何特定实现中,普通char 对象可以采用与带符号字符无符号字符相同的值;哪一个是实现定义的。

于 2013-10-18T09:32:05.567 回答
-1

我会说我知道的...

对于 char 类型 c++ 的大小为 '1' 字节..

如果它是有符号字符,则范围是从 -128 到 127 否则如果它是无符号字符,则范围是从 0 到 256

我们都知道在有符号字符的情况下,一个字节中的 8 位 MSB(即最左边的位)将用于符号,其余 7 位用于范围为 0-2^7(0-127)的值。负符号(逻辑 1)和(逻辑 0)表示 MSB 上的正号。例如(1 0000111=-7,0 0000111=+7)和 1 0000000-128。但是,如果为有符号字符值分配 129,它将自动更改为 -127(即范围内的值 (-128,127)。

在 unsigned char 类型的另一种情况下,所有 8 位都用于值,即范围是 0-2^8(0-255)。这里 0-127 与有符号字符相同,属于 -128 到 0 的可以在无符号字符集中的 128-255 范围内找到。

因此,我们可以说出并发现“有符号”和“无符号”两种类型之间的内存差异,这可能是问题所在。

于 2013-10-18T09:09:57.733 回答