数组的下标具有类型“字符”(array subscript has type 'char&#

2019-06-23 17:02发布

我有以下代码来读取命令行参数。 如果字符串为1个字符长和一个数字我想用其作为退出值。 编译器给我在第二行上的警告(数组下标已键入“焦炭”)中的“&&”之后该错误来自于第二部分。

    if (args[1] != NULL) {
        if ((strlen(args[1]) == 1) && isdigit(*args[1]))
            exit(((int) args[1][0]));
        else
            exit(0);
    }
}

此外,当我使用不同的编译器,我得到下一行(出口)两个错误。

builtin.c: In function 'builtin_command':
builtin.c:55: warning: implicit declaration of function 'exit'
builtin.c:55: warning: incompatible implicit declaration of built-in function 'exit'

Answer 1:

麻烦的是,该isdigit()宏接受一个参数,它是一个整数,或者是值EOF或的值unsigned char

ISO / IEC 9899:1999(C标准-旧),§7.4字符处理<ctype.h> ,¶1:

在所有情况下的参数为int ,其值应是可表示为unsigned char或应等于宏EOF的值。 如果参数为其他值,则行为是不确定的。

在你的平台上, char签订,所以如果你有在0x80..0xFF范围内的角色,它将被作为一个负整数处理。 通常执行的isdigit()宏是使用参数来索引到标志位的阵列。 因此,如果你传递一个char从0x80..0xFF的范围内,你将数组开始之前索引,导致不确定的行为。

#define isdigit(x)  (_CharType[(x)+1]&_Digit)

您可以放心地使用isdigit()在以下两种方式:

int c = getchar();

if (isdigit(c))
    ...

要么:

if (isdigit((unsigned char)*args[1]))
    ...

在后一种情况下,你知道值不会EOF。 请注意,这是不正常:

int c = *args[1];

if (isdigit(c))  // Undefined behaviour if *args[1] in range 0x80..0xFF
    ...

关于“退出函数的定义隐含”的警告意味着你没有包括<stdlib.h> ,但你应该这样做。

您可能还注意到,如果用户给你一个2作为第一个参数的第一个字符,退出状态将是50,而不是2,因为'2'是(通常,在ASCII和UTF-8和8859-1,等)的字符代码50( '0'是48,等)。 你会得到2使用(不含引号) *args[1] - '0'作为参数exit() 你并不需要了解它的表达铸造,但它不会做多大的危害。



Answer 2:

看来你使用编译器提供了ISDIGIT(而不是一个功能,你不会有一个警告,如果是这种情况),使用参数作为数组下标宏。 这就是为什么ISDIGIT接受一个int作为参数,而不是一个字符。

除去警告的一种方式,它投下您字符为int:

isdigit(*args[1]) => isdigit((int)(*args[1]))

第二个警告意味着你要使用的退出功能,但它尚未确定。 这意味着你必须做所需的#include。

#include <stdlib.h> 

位于c-库中的标准使用退出(int)的函数。

顺便说一句,如果这个代码是在你的“主”的功能,你不能查“ARG [1] == NULL”,这可能导致分段故障,如果用户没有提供命令行任何参数。 你必须检查的argc值(INT参数)大于1。



Answer 3:

这是不完全清楚你想要什么 ,得到退出代码,但可能你想args[1][0] - '0'的十进制值的字符表示,而不是字符的代码。

如果你不喜欢它,你就会有副作用,就是该表达式的类型是int ,你不会看到警告。

对于exit你可能忘了,包括头文件。



Answer 4:

试着改变

isdigit(*args[1])

isdigit(args[1][0])

您的其他错误是因为你不使用#include <stdlib.>定义了exit功能。



文章来源: array subscript has type 'char'