【问题标题】:What is the difference between adding these strings?添加这些字符串有什么区别?
【发布时间】:2020-05-19 11:12:53
【问题描述】:

计划 1:

#include <iostream>
using namespace std;

int main() {
    string str;
    char temp = 'a';
    str += temp + "bc";
    cout << str;
    return 0;
}

输出:

未知字符

计划 2:

#include <iostream>
using namespace std;

int main() {
    string str;
    char temp = 'a';
    str += temp;
    str += "bc";
    cout << str;
    return 0;
}

输出:

abc

为什么两个输出不同?两个输出不应该相同吗?

【问题讨论】:

  • 不,它们不应该相同。第一个是未定义的行为。小测验:将char 添加到const char * 会发生什么?
  • char 加上const char[] 不等于char 加上string 后跟const char[] 加上string
  • @SamVarshavchik:'a' 为 1 或 2 时没有可能的编码? ;-)
  • 为了说明,试试这个:cout

标签: c++ string operator-overloading c-strings pointer-arithmetic


【解决方案1】:

此声明

str += temp + "bc";

可以表示为

str = str + ( temp + "bc" );

在子表达式temp + "bc" 中,字符串文字"bc" 被隐式转换为指向其第一个字符的指针,并具有const char * 类型。由于整数提升,例如在 ASCII 表中具有值 97,变量 temp 的值被转换为整数类型。

所以在子表达式中使用了指针算法。表达式temp + "bc" 指向字符串文字之外的内存。所以表达式的结果是未定义的。

如果你会写例如

char temp = 1;

然后表达式 temp + "bc" 指向字符串文字的第二个字符。因此,str 的值将是 'b'

或者要获得与您可以编写的第二个程序相同的结果

str += temp + std::string( "bc" );

至于第二个程序那么在这个语句中

str += temp;
str += "bc";

对于 std::string 类和 charchar * 类型的对象,使用了重载运算符 +=。所以这些陈述是明确定义的。

请注意,您应该明确包含标题 &lt;string&gt;

#include <string>

【讨论】:

    【解决方案2】:

    这一行的程序1

    str += temp + "bc";
    
    1. 计算加法的第一个参数
    2. 右边有一个字符数组:const char[3]
    3. 左边有char,可以自动转换为int
    4. const char[3] 降级为 const char *
    5. 添加int (97) 和const char * 是可行的,但结果点超出缓冲区范围。
    6. 那么您正在使用basic_string::operator+=( const CharT* s );,但参数无效。缓冲区溢出。

    程序 2。 没有这种未定义的行为,并且使用了std::string 形式的运算符。

    另一个合理的版本是:

    str = str + temp + "bc";
    

    现在每次添加都会创建一个std::string

    【讨论】:

      【解决方案3】:

      std::string 类具有重载的 ++= 运算符,允许您使用它们将 std::strings 与单个字符和字符数组相互连接。

      但就像在 C 中一样,"bc" 不是std::string,而是const char [3](3 个字符的常量数组)。数组通常会自动转换 (decay) 为指向其第一个元素的指针。它也发生在这里。

      str += "foobar"; 将指针指向的字符一个接一个地追加,直到碰到终止字符串的空字节。

      您可以将整数添加到指针:str += "foobar" + 3; 会将 "bar" 附加到字符串。

      在 C++ 中,chars 只是小整数。所以'a' + "bc" 实际上意味着97 + "bs"(假设你的编译器使用ASCII,所有常见的都这样做)。

      这会形成一个超出数组范围的指针并导致未定义的行为。

      您看到的随机字符是位于 "bc" 数组之后 97 个字节的内存内容,由该内存中的随机空字节终止。

      【讨论】:

        猜你喜欢
        • 2015-08-08
        • 1970-01-01
        • 2012-06-15
        • 2017-01-24
        • 1970-01-01
        • 2020-06-28
        • 1970-01-01
        相关资源
        最近更新 更多