The header
<ctype.h>
declares several functions useful for classifying
and mapping characters. In all cases the argument is anint
,the
value of which shall be representable as anunsigned char
or shall
equal the value of the macroEOF
. If the argument has any other value,
the behavior is undefined.
是不确定的行为?:
#include <ctype.h> #include <limits.h> #include <stdlib.h> int main(void) { char c = CHAR_MIN; /* let assume that char is signed and CHAR_MIN < 0 */ return isspace(c) ? EXIT_FAILURE : EXIT_SUCCESS; }
标准是否允许将char传递给isspace()(char到int)?换句话说,转换为int后的char是否可表示为unsigned char?
这是wiktionary defines “representable”:
Capable of being represented.
char是否能够表示为unsigned char?是. §6.2.6.1/ 4:
Values stored in non-bit-field objects of any other object type
consist of n×
CHAR_BIT
bits,where n is the size of an object of that
type,in bytes. The value may be copied into an object of type
unsigned char [n] (e.g.,by memcpy); the resulting set of bytes is
called the object representation of the value.
sizeof(char)== 1因此它的对象表示是unsigned char [1],即char能够表示为unsigned char.我哪里错了?
具体例子,我可以将[-2,-1,1]表示为[0,1,2,3].如果我不能那么?
相关:根据§6.3.1.3,如果INT_MAX> = UCHAR_MAX,则isspace((unsigned char)c)是可移植的,否则它是实现定义的.
解决方法
the value of which shall be representable as an unsigned char or shall
equal the value of the macro EOF
如果我们阅读第7.4节字符处理< ctype.h>从Rationale for International Standard—Programming Languages—C开始说(强调我的前进):
Since these functions are often used primarily as macros,their domain
is restricted to the small positive integers representable in an
unsigned char,plus the value of EOF. EOF is traditionally -1,but may
be any negative integer,and hence distinguishable from any valid
character code. These macros may thus be efficiently implemented by
using the argument as an index into a small array of attributes.
所以有效值是:
>可以适应unsigned char的正整数
> EOF是一些实现定义的负数
即使这是C99的基本原理,因为您所指的特定措辞不会从C99更改为C11,因此基本原理仍然适用.
我们还可以找到为什么接口使用int作为参数而不是char,从7.1.4节使用库函数,它说:
All library prototypes are specified in terms of the “widened” types
an argument formerly declared as char is now written as int. This
ensures that most library functions can be called with or without a
prototype in scope,thus maintaining backwards compatibility with pre-C89 code. Note,however,that since functions like printf and scanf use variable-length argument lists,they must be called in the scope of a prototype.