我在 C 中有以下代码:
char input[127] = "hello world";
isxdigit(input[0]);
但我收到以下警告:
warning: array subscript has type 'char'
是什么原因以及如何解决?
我在 C 中有以下代码:
char input[127] = "hello world";
isxdigit(input[0]);
但我收到以下警告:
warning: array subscript has type 'char'
是什么原因以及如何解决?
原因是在您的 C 实现中,isxdigit()
是使用数组查找作为宏实现的。
只要您的输入字符串仅包含字符 <=127,您就可以使用强制转换来修复它:
isxdigit ((int)input[0]);
或者,如果您认为演员表丑陋,请借助良性表达,例如添加 0:
isxdigit (0 + input[0]); /* Avoid cast by using an int-typed expression. */
isxdigit (+input[0]); /* Same thing using unary plus instead of addition. */
由于 C 标准要求它isxdigit
也是一个函数,因此您可以选择调用函数而不是宏:
(isxdigit)(input[0]);
甚至
#undef isxdigit
isxdigit(input[0]);
这应该不会产生警告,因为input[0]
被提升为int
(假设先验#include <ctype.h>
。)
char
正如 cmaster 正确指出的那样,一旦您签署并包含负值,这些解决方案就会崩溃。在这种情况下,您必须先转换为(如果需要unsigned char
,再转换为)。int
原因是isxdigit
有原型int isxdigit(int)
。因此,要删除此警告,您应该将参数显式转换为int
isxdigit((int)input[0]);
关键是,标准没有定义 char 类型是否是有符号的,将这个决定留给实现。因此(int)(char)128
可以评估为 128 或 -128。正如您的编译器所注意到的那样,后者显然对数组索引不利(聪明的家伙,那个编译器)。
所以正确的解决方法是强制转换为unsigned char
,而不是int
。
isxdigit((unsigned char)input[0])
如果你选择其他错误的答案,你最终可能会在 utf8 字符串上崩溃!(utf8 对多字节字符使用大于 127 的代码。)
编辑:当然,Pascal Cuoq 说得对,不允许这样的实现将 isxdigit 实现为表查找宏,但是,我所说的适用于任何出现此编译器警告的情况,包括您实现的任何查找表你自己。非常不幸的是,char 的符号没有定义,人们应该更好地了解这个问题并知道如何正确地避免它。