13

这是一个代码 -

  1 int main(int argc, char *argv[])
  2 {
  3     signed char S, *psc;
  4     unsigned char U,  *pusc;
  5     char C, *pc;
  6 
  7     C = S;
  8     C = U;
  9 
 10     pc = psc;
 11     pc = pusc;
 12 
 13     return 0;
 14 }

$ gcc test.cpp -o a
test.cpp: In function ‘int main(int, char**)’:
test.cpp:10:7: error: invalid conversion from ‘signed char*’ to ‘char*’ [-fpermissive]
test.cpp:11:7: error: invalid conversion from ‘unsigned char*’ to ‘char*’ [-fpermissive]

这是在英特尔 32 位机器上的 Ubuntu 12.10 上的 gcc 版本 4.6.3 上编译的。

考虑到该char类型unsigned char在 x86 上。-

如果第 7 行和第 8 行对非指针类型的赋值正常,为什么第 10 行和第 11 行的指针类型会抛出错误?

另外,应该C = U成功而不需要演员吗?

4

4 回答 4

7

首先,重要的是要强调一个事实,即char,signed charunsigned char都是不同的类型。C++11 标准的 4.10 节定义了不同类型指针之间的三种可能的标准指针转换:

1. 空指针常量是整数类型的整数常量表达式 (5.19) 纯右值,其计算结果为零或 std::nullptr_t 类型的纯右值。空指针常量可以转换为指针类型;结果是该类型的空指针值,并且可以与对象指针或函数指针类型的所有其他值区分开来。这种转换称为空指针转换。相同类型的两个空指针值应比较相等。将空指针常量转换为指向 cv 限定类型的指针是一次转换,而不是指针转换后跟限定转换 (4.4) 的顺序。整数类型的空指针常量可以转换为 std::nullptr_t 类型的纯右值。[ 注意:生成的纯右值不是空指针值。——尾注]

这无关紧要,因为我们这里没有空指针类型nulltptr_t

2. “指向 cv T 的指针”类型的纯右值,其中 T 是对象类型,可以转换为“指向 cv void 的指针”类型的纯右值。将“指向 cv T 的指针”转换为“指向 cv void 的指针”的结果指向类型 T 的对象所在的存储位置的开始,就好像该对象是类型 T 的最派生对象 (1.8) (即,不是基类子对象)。空指针值转换为目标类型的空指针值。

这不适用,因为目标类型不是void. 最后,

3. 类型“指向 cv D”的纯右值,其中 D 是类类型,可以转换为类型“指向 cv B”的纯右值,其中 B 是 D 的基类(第 10 条)。如果 B 是D 的不可访问(第 11 条)或模棱两可的(10.2)基类,需要这种转换的程序是格式错误的。转换的结果是指向派生类对象的基类子对象的指针。空指针值转换为目标类型的空指针值。

signed char不是 的基类char,所以这也不适用。

因此,无法执行从signed charto的隐式标准指针转换。char

另一方面,根据第 4.7 节中的规定,允许整数类型值之间的转换。

于 2013-02-23T21:57:18.943 回答
3

C ++没有自动指针转换,赋值两边的指针类型是什么都没有关系,如果它们不同,则需要强制转换。

于 2013-02-23T21:55:38.163 回答
2

char是与unsigned char和不同的类型signed char。它只保证具有与其中一个等效的值表示,但它仍然是一种不同的类型。因此,您不能从其中一个unsigned char*或转换signed char*char*(即,除非您使用 a reinterpret_cast)。C++ 只是不允许像这样在不同类型之间进行指针转换,因为这样一种类型可能会伪装成另一种类型。

但是,从其中一个unsigned charsigned char到的转换char是完全可以的,因为它只涉及其值的转换。

以这种方式考虑:您可以将 an 转换int为 a float,但不能将 an 转换int*为 a float*

于 2013-02-23T21:55:51.493 回答
0

我可能是错的,但如上所述,当你分配“C = S; C = U;”时,C++ 会自动转换它,有点像你做 "char x = "h"; printf("%i", x );"。但是,指针指向内存中的特定位置,并且该位置具有大小。因此,虽然转换只是从不同的角度查看值,但指向不同的值可能涉及更改所指向的值的大小。

于 2013-02-23T22:01:13.357 回答