为什么参数为isdigit整数?

时间:2017-10-09 17:37:09

标签: c++

函数std::isdigit是:

  int isdigit(int ch);

返回(如果字符是数字字符则为非零值,否则为零。)闻起来函数是从C继承的,但即使这样也无法解释为什么参数类型为int而不是{{ 1}}同时......

  

如果ch的值不能表示为,则行为未定义   unsigned char并且不等于EOF。

charisdigits而不是int有什么技术原因吗?

2 个答案:

答案 0 :(得分:4)

原因是允许EOF作为输入。而EOF是(来自here):

  

EOF类型的EOF整数常量表达式和负值

答案 1 :(得分:1)

可接受的答案是正确的,但我认为这个问题值得更多详细说明。

根据您的实现,C ++中的char是带符号的还是无符号的(而且,它是与signed charunsigned char不同的类型)。

在C长大的地方,char通常是无符号的,并假定是一个可以表示[0..2 ^ n-1]的 n 位字节。 (是的,有些机器的字节大小不是8位。)实际上,char被认为与字节几乎没有区别,这就是为什么像memcpy这样的函数采用char *而不是而不是像uint8_t *之类的东西,为什么sizeof char总是1,为什么CHAR_BITS没有命名为BYTE_BITS

但是作为C ++的基线的C标准仅承诺char可以在执行字符集中保留任何值。它们可能具有其他价值,但不能保证。源字符集(基本上是7位ASCII减去一些控制字符)需要类似97的值。有一小段时间,执行字符集可能会更小,但实际上几乎从未如此。最终,明确要求char的大小足以容纳8位字节。

但是范围仍然不确定。如果未签名,则可以依靠[0..255]。但是,从理论上讲,带符号的字符可以使用符号+大小表示形式,该范围为[-127..127]。请注意,只有255个唯一值,而不是256个值([-128..127]),就像您从二进制补码中获得的那样。如果您足够熟练地使用语言,则可以辩称您无法将8位字节的每个可能值存储在char中,即使这是整个语言及其运行时库设计的基本假设。我认为C ++最终通过实际上要求带符号的char使用二进制补码来封闭C ++ 17或C ++ 20中的明显漏洞,即使较大的整数类型使用符号+量级。

当需要设计基本输入/输出功能时,他们不得不考虑如何返回值或信号,该信号或信号已经到达文件末尾。决定使用特殊值而不是带外信令机制。但是要使用什么价值? Unix人士通常可以使用[128..255],其他人可以使用[-128 ..- 1]。

但这仅在您处理文本时使用。 Unix / C人们认为文本字符和二进制字节值是同一回事。因此getc()也用于从二进制文件读取字节。 char的所有256个可能值(无论其有无签名)都已声明。

K&R C(在第一个ANSI标准之前)不需要功能原型。编译器对参数和返回类型进行了假设。这就是C和C ++具有“默认升级”的原因,即使它们现在不如以前那么重要了。实际上,您不能从函数返回小于int的任何东西。如果这样做的话,无论如何它只会被转换为int

因此,自然的解决方案是让getc()返回一个int,其中包含字符值一个特殊的文件末尾值,被想象为{{1} },-1的宏。

默认的提升不仅使函数不能返回小于EOF的整数类型,而且还使传递小类型的内容变得困难。因此,int也是期望字符的函数的自然参数类型。因此,我们最终得到了像int这样的函数签名。

如果您是Posix粉丝,基本上这就是您所需要的。

对于我们其余的人,还有一个陷阱:如果您的int isdigit(int ch)已签名,则-1可能表示您的执行字符集中的合法字符。您如何区分它们?

答案是,函数实际上根本不会使用char值进行交易。他们确实使用char装扮成unsigned char的值。

int