【问题标题】:How type Inference "auto" and call by reference works?类型推理“自动”和引用调用如何工作?
【发布时间】:2018-09-29 20:02:50
【问题描述】:

&c 在这个循环和分配c = toupper(c) 时如何工作?

string str = "hello";

for (auto & c: str)
  c = toupper(c);

你能解释一下吗?

【问题讨论】:

  • 我不确定我是否理解您的问题。您是否有特定的错误或错误消息,或者您是否专门询问&c 声明

标签: c++ string pointers


【解决方案1】:

首先,请注意std::toupper 具有未定义行为,如果它提供了除EOF 之外的负值。对于大多数编译器,char 默认是有符号类型。在典型的 8 位字节计算机上,这意味着如果 c 的值不在 ASCII 范围内,即 0 到 127,那么它是负数,你会得到 UB。

那个问题的简单解决方案是将参数转换为unsigned char

auto to_upper( const char c )
    -> char
{
    using Byte = unsigned char;
    return static_cast<char>( toupper( static_cast<Byte>( c ) );
}

默认情况下,此函数仍仅适用于 ASCII 字符,即字母 A 到 Z,因为它采用 C 级别语言环境指定的编码,默认情况下为 "C",基本上仅限于 ASCII。但至少它避免了未定义的行为。所以让我们假设您的示例使用它,

for( auto& c : str ) c = to_upper( c );

这是一个基于范围的for 循环,它遍历str 中的所有项目,将引用c 绑定到每个项目,并在该绑定生效的情况下执行循环体。由于str 的项目属于char 类型,所以auto 将被推导出为char。所以和写for( char&amp; c : str ) ...是一样的。

所以默认情况下它将str中的所有ASCII字符大写。

在 Windows 中,如果 C 语言环境已通过 setlocale( LC_ALL, "" ) 设置,则假定编码将是 Windows ANSI,并且如果 str 包含具有该编码的字符,to_upper 将正确执行其大写工作。这意味着在 Windows 中可以将其用于例如大写挪威字符串,如"Blåbærsyltetøy",前提是 Windows 的语言环境是使用 Windows ANSI Western 的语言环境。

在 *nix 中,调用 setlocale 无济于事,因为用户的本地语言环境将指定 UTF-8 编码,其中 ASCII 之外的每个字符表示为两个或更多字节 > 127。

【讨论】:

    【解决方案2】:

    auto &amp; c 等价于char &amp; c,它是对字符串中每个字符的引用。更新引用的值会改变字符串中被引用的字符。

    上述代码的结果将是一个大写字符串。

    【讨论】:

    • 我不会说auto 等同于char,而是根据上下文推断这里是char
    猜你喜欢
    • 1970-01-01
    • 2023-01-12
    • 2019-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多