为什么C ++不接受有符号或无符号的字符数组

时间:2018-03-07 06:01:35

标签: c++ arrays char

我在Visual Studio 2017中以纯模式使用C ++。该编译器编译下面的语句而没有抱怨:

const char * AnArrayOfStrings[]  = {"z1y2x3w4", "Aname"};

但是,如果我更改上述语句以指定char是有符号或无符号的,则编译器会发出 C2440 错误。例如,下面的语句是编译:

const signed   char * AnArrayOfStrings2[] = {"z1y2x3w4", "Aname"};

const unsigned char * AnArrayOfStrings2[] = {"z1y2x3w4", "Aname"};

我没有看到编译器在明确显示char的符号时拒绝编译语句的原因。

我的问题是:是否有充分的理由让我没有看到编译器拒绝编译这些语句?

感谢您的帮助(我在StackOverflow中进行了研究,C ++文档,我使用过谷歌,并且为了找到答案而咨询了大约十几本C / C ++书籍,但仍有一个原因让我望而却步。)< / p>

2 个答案:

答案 0 :(得分:15)

"z1y2x3w4"const char[9],并且没有从const char*const signed char*的隐式转换。

您可以使用reinterpret_cast

const signed char * AnArrayOfStrings[]  = {reinterpret_cast<const signed char *>("z1y2x3w4"),
                                           reinterpret_cast<const signed char *>("Aname")};

答案 1 :(得分:3)

如果你编译上面的代码

const signed   char * AnArrayOfStrings2[] = {"z1y2x3w4", "Aname"};  

在C中使用选项-Wall使用gcc然后它会发出以下警告

test.c:5:49: warning: pointer targets in initialization differ in signedness [-Wpointer-sign]
  const unsigned   char * AnArrayOfStrings2[] = {"z1y2x3w4", "Aname"};
                                                 ^
test.c:5:49: note: (near initialization for 'AnArrayOfStrings2[0]')
test.c:5:61: warning: pointer targets in initialization differ in signedness [-Wpointer-sign]
  const unsigned   char * AnArrayOfStrings2[] = {"z1y2x3w4", "Aname"};  

AnArrayOfStrings2"z1y2x3w4"的元素类型不同。 AnArrayOfStrings2[0]的类型为const signed char *,而"z1y2x3w4"的类型为const char[9] 相同的代码会引发C ++中的错误。您需要使用显式强制转换才能使其在C ++中工作。

解释原因

const char * AnArrayOfStrings[]  = {"z1y2x3w4", "Aname"}; 

工作我将采用简单的例子

const char c[] = "asc";
const char *p1 = c;           // OK
signed const char *p2 = c;    // Error
unsigned const char *p3 = c;  // Error

在上述代码段的第二行中,c将转换为const char *,从而使p1c兼容类型。
在第三行中,p2c的类型不兼容,编译器将在C ++中引发错误(C中的警告)。第4行也是如此。

如果我们为int类型

采取另一个示例
const int i[] = {1,2,3};
const int *ii = i            // OK
signed const int *si = i;    // OK
unsigned const int *usi = i; // Error  

前两个指针初始化作为int工作,没有任何说明符等同于signed int(但char不是这样),因此类型是兼容的。在最后一种情况下,初始化失败,因为const int *signed const int *unsigned const int *不兼容。