【问题标题】:What is the macro definition of isupper in C?C语言中isupper的宏定义是什么?
【发布时间】:2010-08-04 06:11:20
【问题描述】:

我想知道“isupper”宏是如何在 C/C++ 中定义的。能否请您提供相同的信息或指向我可用的资源。我尝试查看 ctype.h 但无法弄清楚。

【问题讨论】:

    标签: c++ c macros definition


    【解决方案1】:

    它是由实现定义的——每个供应商都可以而且通常会以不同的方式来做。

    最常见的通常涉及“特征”表 - 每个字符都有一个元素的数组,该元素的值是标志的集合,表示有关字符的详细信息。一个例子是:

     traits[(int) 'C'] = ALPHA | UPPER | PRINTABLE;
    

    在这种情况下,isupper() 将类似于:

     #define isupper(c) ((traits[(int)(c)] & UPPER) == UPPER)
    

    【讨论】:

      【解决方案2】:

      它是特定于实现的。一种明显的实现方法是:

      extern char *__isupper;
      #define isupper(x) ((int)__isupper[(x)])
      

      其中__isupper 指向由区域设置确定的 0 和 1 数组。然而,这种技术已经失宠,因为在共享库中访问全局变量效率相当低,并且会产生永久的 ABI 要求,而且它与 POSIX 线程本地语言环境不兼容。

      在纯 ASCII 或纯 UTF-8 实现上实现它的另一种明显方法是:

      #define isupper(x) ((unsigned)(x)-'A'<='Z'-'A')
      

      【讨论】:

      • 非常好,我从来没想过(然后我再也没试过:])
      • 顺便说一下,所有实现应该#define isdigit(x) ((unsigned)(x)-'0'&lt;10),因为ISO C要求行为与这个表达式相同并且它是最优的。
      • 我不像你对 UTF8 那样有信心。当然,ASCII 范围之外的所有其他语言也都有大写字母吗?而且,如果你把它留在那里,你可能应该说“Unicode”。 UTF8 是编码,不是字符集。
      • @paxdiablo,这是isupper 而不是iswupper。在 UTF-8 中,ASCII 范围之外的所有字节本身没有意义,仅作为多字节序列的一部分,因此非宽 is* 函数对于非 ASCII 字节总是返回 0。
      • @R,我认为您在这里混淆了术语字节。一个字节一个字符。 ISO C 中没有多字节字符。如果底层字符集是 Unicode(无论编码如何),isupper 及其兄弟也必须处理其他语言 - 它是特定于语言环境的。
      【解决方案3】:

      这是一个函数,而不是宏。 isupper() 的函数定义因语言环境和当前字符集等因素而异 - 这就是为什么有专门用于此目的的函数。

      对于 ASCII,由于字母的分配方式,实际上很容易对此进行测试。如果字符的 ASCII 码介于 0x410x5A 之间,则为大写字母。

      【讨论】:

        【解决方案4】:

        它实际上相当复杂,例如在 GCC 中。但是 isupper 的一个简单实现可以(尽管它有一个双重评估错误)最简单地定义为:

        #define isupper(c) (c >= 'A') & (c

        http://ideone.com/GlN05

        GCC 专门检查当前语言环境的字符中的位 0 是否为 1:

        (*__ctype_b_loc ())[(int) (c)] & (unsigned short int) (1

        其中 __ctype_b_loc() 是一个函数,它返回指向当前语言环境中的字符数组的指针,其中包含当前字符集中每个字符的特征。

        【讨论】:

        • 这个宏被破坏了,因为它在参数周围缺少括号并且它两次评估它的参数(想想isupper(*s++)...)。您需要转换为 unsigned 并使用无符号溢出语义来测试范围,而无需多次评估参数。
        • 公平地说,我指出了双重评估错误。 :-)
        猜你喜欢
        • 1970-01-01
        • 2011-07-03
        • 2012-08-16
        • 1970-01-01
        • 1970-01-01
        • 2011-10-08
        • 2014-09-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多