【问题标题】:Why does neither C nor Objective-C have a format specifier for Boolean values?为什么 C 和 Objective-C 都没有布尔值的格式说明符?
【发布时间】:2015-04-07 23:00:13
【问题描述】:

我正在开发的应用程序有一个带有布尔“已批准”字段的信用响应对象。我试图在 Objective C 中注销这个值,但由于没有布尔值的格式说明符,我不得不求助于以下内容:

NSLog("%s", [response approved] ? @"TRUE" : @"FALSE");

虽然不可能,但我更愿意执行以下操作:

NSLog("%b", [response approved]);

...其中“%b”是布尔值的格式说明符。

在做了一些研究之后,似乎一致的 consensus 是 C 和 Objective-C 都没有相当于“%b”的说明符,大多数开发人员最终都自己动手(类似于上面的选项 #1) .

显然 Dennis Ritchie & Co. 在编写 C 时就知道他们在做什么,我怀疑这个丢失的格式说明符是个意外。我很想知道这个决定背后的理由,所以我可以向我的团队(他们也很好奇)解释一下。

编辑: 下面的一些答案表明这可能是一个本地化问题,即“TRUE”和“FALSE”过于特定于英语。但这不是所有语言都面临的困境吗?即不仅仅是C和Objective-C? Java 和 Ruby 等能够实现“True”和“False”布尔值。不知道为什么这些 langs 的作者没有类似地选择这个选项。

此外,如果本地化是问题所在,我预计它也会影响语言的其他方面。以受保护的关键字为例。 C 使用诸如“include”、“define”、“return”、“void”等英文关键字,这些关键字对于非英语使用者来说可能比“true”或“false”等关键字更难解析。

【问题讨论】:

  • 您的第一个代码 sn-p 使用 %s 和 Objective-C 字符串文字 (@"")。使用 %@ 或使用 C 字符串文字。此外,您可以将布尔值的字符串选择封装在一个内联函数中:static inline NSString* bool_name(BOOL val) { return val ? @"TRUE" : @"FALSE"; },然后是 NSLog(@"%@", bool_name([response approved]));

标签: objective-c c format-specifiers


【解决方案1】:

纯 C(回到 K&R 变体)实际上没有布尔 类型,这就是原生 printf 和表兄弟没有原生布尔格式说明符的根本原因。表达式可以计算为零或非零整数值,这在 if 语句中分别解释为假或真,在 C 中。(理解这一点是理解令人愉快的 !! “bang bang operator”的语义的关键语法。)

C99 did add a _Bool type,尽管除非您使用最纯粹的 C,否则您不太可能需要它;派生语言和通用平台已经具有通用布尔类型或 typedef。)

BOOL 类型是一个 ObjC 构造,-[NSString stringWithFormat:](和NSLog)根本没有额外的格式说明符来做任何特殊的事情。它当然可以(除了%@),并选择一些合理的字符串放在那里;我不知道是否曾经考虑过这样的事情,但无论如何它让我觉得它与所有其他格式说明符在本质上是不同的。您如何知道适当地本地化或大写“yes”或“no”(或“true”或“false”?)等的字符串表示形式?没有其他格式说明符会导致库做出这样的决定;所有其他都是精确的数字或​​插入另一个方法调用的字符串结果。这似乎很繁重,但让您选择您真正想要的文本可能是最优雅的解决方案。

【讨论】:

    【解决方案2】:

    格式化程序应该显示什么? 0 & 1?真假?是与否? -1 和 1?其他语言呢?

    没有始终如一的正确答案,因此他们将其推给了应用程序开发人员,对他们来说,这将是一个更清晰(而且仍然简单)的选择。

    【讨论】:

    • 这不是所有语言都面临的困境吗?即不仅仅是C和Objective-C? Java 和 Ruby 等能够实现“True”和“False”布尔值。不知道为什么这些语言的作者没有同样地选择这个选择。此外,如果本地化是问题所在,我希望它也会影响语言的其他方面。以受保护的关键字为例。 C 使用诸如“include”、“define”、“return”、“void”等英文关键字,这些关键字对于非英语使用者来说可能比“true”或“false”等关键字更难解析。
    • @toomanyrichies 合理的问题:Java 和 Ruby。回复:语言环境,我建议在存在且仅在源代码中有意义的实际语言关键字(“void”,“return”)与库在运行时使用的字符串之间存在区别,用户最终可能会看到.
    【解决方案3】:

    在 C 早期,charshort 没有数字 printf() 说明符,因为几乎不需要它。现在有"%hhd""%hd"。任何比int/unsigned 窄的类型都被提升了。

    今天,在 C 语言中,_Bool 类型可能会打印为 "%d"

    #include <stdio.h>
    int main(void) {
      _Bool some_bool = 2;
      printf("%d\n", some_bool); // prints 1 (or 0 when false)
      return 0;
    }
    

    C 中缺少的链接是它缺少扫描_Bool 的格式说明符。这导致了以下各种解决方案,这些解决方案对于“T”或“false”等输入并不令人满意。

      _Bool some_bool;
      int temp;
      scanf("%d", &temp);
      some_bool = temp; 
    

    【讨论】:

      猜你喜欢
      • 2012-06-22
      • 1970-01-01
      • 2011-02-05
      • 2014-07-14
      • 1970-01-01
      • 2011-02-26
      • 2011-10-08
      • 1970-01-01
      • 2023-03-26
      相关资源
      最近更新 更多