6

当我在本例中使用 char 数组下标时:

int main(){
    char pos=0;
    int array[100]={};

    for(pos=0;pos<100;pos++)
        printf("%i\n", array[pos]);

    return 0;
}

我收到警告说我正在使用 char 数组下标:

警告:数组下标的类型为 'char' [-Wchar-subscripts]

没关系,因为我启用了这个警告。

GCC 手册说:

-Wchar-subscripts 如果数组下标的类型为“char”,则发出警告。这是错误的常见原因,因为程序员经常忘记这种类型是在某些机器上签名的。此警告由 -Wall 启用。

所以这个警告应该防止使用负数组索引。我的问题是,为什么这个警告只在 char 上有效,而不在其他有符号类型上有效?

谢谢你。

4

3 回答 3

8

这是因为int总是签名。

char不必。

char可以签名或未签名,具体取决于实现。(有三种不同的类型 - char, signed char, unsigned char

但问题是什么?我只能使用 0 到 127 之间的值。这会默默地伤害我吗?

哦,是的,它可以。

//depending on signedess of char, this will
//either be correct loop,
//or loop infinitely and write all over the memory
char an_array[50+1];
for(char i = 50; i >= 0; i--)
{
    an_array[i] = i;
    // if char is unsigned, the i variable can be never < 0
    // and this will loop infinitely
}
于 2013-02-21T16:00:42.137 回答
2

简单地说,它抱怨你的索引是 type character

只需转换pos为an int,警告就会消失。

至于为什么会出现这个警告,你自己说了。char数据类型只能处理 0 - 255(如果无符号)甚至 127(如果有符号)的值。对于普通数组,这是一个相当少的数字,您可能会很快忘记该signed位并意外访问数组位置 -128(通过实际访问数组元素 128)。

只要您的数组小于 127,就可以了,您可以忽略警告,但老实说……内存占用中的这三个额外字节不会使您的应用程序效率低下,不是吗?

于 2013-02-21T15:59:36.393 回答
0

因为本机char可以是未签名的或已签名的。

请注意,使用负下标是完全合法的。例如:

int arr[10];
int *ptr = arr[5];

现在我可以使用ptr[-1]相当于arr[4]. 如果char在实现中碰巧是无符号的,它永远不会是负值。

于 2013-11-11T02:48:21.933 回答