为什么在此C代码中将字母分成多个范围?


161

在一个自定义库中,我看到了一个实现:

inline int is_upper_alpha(char chValue)
{
    if (((chValue >= 'A') && (chValue <= 'I')) ||
        ((chValue >= 'J') && (chValue <= 'R')) ||
        ((chValue >= 'S') && (chValue <= 'Z')))
        return 1;
    return 0;
}

复活节彩蛋,还是与标准C / C ++方法相比有什么优势?

inline int is_upper_alpha(char chValue)
{
    return ((chValue >= 'A') && (chValue <= 'Z'));
}

请注意,在EBCDIC中,小写字母的字符范围在大写字母的字符范围之前,并且都在数字之前。这与基于ASCII的编码(例如8859- x系列,或Unicode,或CP1252,或…)。
乔纳森·勒夫勒

1
注意:如果'J' - 'I''S' - 'R'都相等1,那么我希望一个合理的优化器可以将前者变成后者。
Matthieu M.

Answers:


214

这段代码的作者可能必须支持EBCDIC在某些时候,其中字母的数值是不连续的(之间存在着差距IJ并且RS正如你可能已经猜到了)。

值得一提的是,C和C ++标准只保证字符09具有连续的数值正是这个原因,所以这些方法都不是严格符合标准的。


64
真正的WTF是为什么原始作者没有发表评论:// In the EBCDIC coding, the alphabet has gaps between these values. See URL: xxxx for details。然后,您甚至都不必问这个问题。您将在代码中内置答案。
abelenky 2015年

66
@abelenky如果该代码最初是用于通常使用ebcdic的系统,则该代码在当时似乎很明显并且不需要注释,但是不幸的是,旧代码中看起来不错的东西现在看起来很奇怪。

26
@abelenky:真正的 WTF是为什么原始作者未使用标准功能的原因,即return ( isalpha( chValue ) && isupper( chValue ) )...
DevSolar,2015年

4
@Damon:这不是问题。即使在没有本地使用该编码的系统上,您也可能必须处理 “外来”编码。因此,将您的语言环境设置为给定的编码,然后您必须使程序员不厌其烦,程序员实际上使用了标准函数,而不是像上面那样进行“智能”编码,以为他知道自己的程序会遇到每种编码...
DevSolar 2015年

6
如果它是为支持1970年代的EBCDIC而编写的,那么isalpha和isupper甚至是ANSI还是当时受大多数编译器支持?
nickalh'5

54

看起来它试图同时覆盖EBCDIC和ASCII。您的替代方法不适用于EBCDIC(它有误报,但没有误报)

C和C ++ 确实要求它们'0'-'9'是连续的。

请注意,标准库调用确实知道它们是在ASCII,EBCDIC还是其他系统上运行,因此它们更具可移植性,并且效率可能更高。


5
std::isupper实际查询当前安装的全局C语言环境。
灵溪2015年

1
是的,你是对的。该方法的编写涵盖了两种编码。感谢你的回答!
Vladimir Ch。

4
@Lingxi:是的,但这并不意味着您可以将语言环境从ASCII切换到EBCDIC。'A'必须保留,'A'而不受地区限制。ASCII到UTF-8,这是可能的。
MSalters 2015年

2
@Lingxi:是的,std::isupper查询当前安装的全局C语言环境,但是解释字符文字的编译阶段则不。
Lightness Races in Orbit

1
@Lingxi-请注意。std::isupper在大多数情况下是否真的需要怀疑。它尊重用于用户输入的语言环境。但是,在解析文件,与数据库交互时,通常需要使用其他语言环境。此外,至少在Linux上,这些与语言环境相关的调用非常慢-例如,std::isalpha在实际比较单个字符之前,两次调用dynamic_cast来“查找”适当的语言环境实现。
ibre5041 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.