2013-02-21 75 views
6

当我用字符数组下标如本例:字符数组下标警告

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

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

    return 0; 
} 

我得到警告说,我使用的字符数组下标:

警告:数组下标具有类型“ char'[-Wchar-subscripts]

这是好的,因为我已启用此警告。

GCC手册说:如果数组下标具有类型 “CHAR”

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

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

谢谢。

+0

请注意,您应该将'size_t'用于数组元素,而不是'char'。 – netcoder 2013-02-21 16:05:25

回答

8

这是因为int总是被签名。

char不必。

char可以有符号或无符号,具体取决于实现。 (有三种不同的类型 - charsigned charunsigned 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 
} 
+0

啊我现在看到它。感谢claryfiing。好的技巧循环索引。谢谢。 – Mihalko 2013-02-21 16:26:33

+0

@Mihalko好吧,这不是一个提示,这是一个警告;) – milleniumbug 2013-02-21 16:31:33

+1

这里的问题是,你在循环中比较char wuth'> = 0'。数组索引是完全不相关的。那么为什么要对该指数给出警告?它应该警告比较,这在某些机器上可能总是如此。 – 2013-11-11 03:31:23

2

说白了,它是在抱怨你的索引是character

只需将pos转换为int,警告即会消失。

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

只要你的数组小于127,你会好起来的,你可以忽略这个警告,但是让我们老实说...内存占用中的这三个额外的字节不会让你的应用程序效率低下,它?

+0

是的,我知道为什么警告那里,但想知道为什么海湾合作委员会只有投诉类型字符。无论如何,因为mileniumbug的回答明确。 – Mihalko 2013-02-21 16:30:05

0

因为原生char可以是无符号或有符号的。

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

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

现在我可以用ptr[-1]这相当于arr[4]。如果char恰好在实现中未签名,则它永远不会是负值。