【问题标题】:Strange output of cout on a char array when initialized in the declaration? Only happens when I declare another array following this one [duplicate]在声明中初始化时,字符数组上 cout 的奇怪输出?仅当我在此之后声明另一个数组时才会发生[重复]
【发布时间】:2020-03-04 03:19:24
【问题描述】:

非常简单的代码,输出我看不懂...

#include  <iostream>

using namespace std;

int main() {

    char text1[] = {'v', 'e', 'r', 'y'};
    cout << text1 <<  endl;
    char text2[] = "strange";
    cout << text2 << endl;

    return 0;
}

由于某种原因,我得到了这个输出:

very�>��

奇怪

每次输出为“非常”时,第二个数组中的字符数量相同。如果我将第一行更改为

,则此输出正确
char text1[] = "very";

或者如果我不声明和计算第二个数组。

必须与使用 {'', '', '', ...} 初始化 char 的方式有关。我注意到在这种情况下 sizeof(text1) 是 4 并且在使用的情况下 char text1[] = "非常"; sizeof(text1) 为 5,最后一个位置留空。声明第二个 char 时,第一个 char sizeof 仍然准确,但是第二个 char 位于内存中第一个 char 之后的位置。

如果我这样重写程序...

int main() {

    char text1[] = {'v', 'e', 'r', 'y'};
    char text2[] = "strange";
    cout << text1 <<  endl;
    cout << text2 << endl;

    return 0;
}

输出变成:

verystrange

strange

似乎如果我声明更多的 char 数组,它总是将最后一个放在第一个 (text1[]) 之后,并且它会在内存中向前碰撞其他的以腾出空间。它只发生在使用 {};初始化。 真的只是想知道这里发生了什么...我看不出这会导致编写良好的程序出现任何问题。

【问题讨论】:

  • 您是否碰巧在您的 C 或 C++ 书籍的某处遇到纯字符文本字符串必须以空字节或 '\0' 结尾?因为这是 C 和 C++ 处理纯文字字符串的唯一方式?
  • cout &lt;&lt; &lt;char *&gt; 需要一个以空字符结尾的字符串,并且您的第一个 char[] 数组不是以空字符结尾的。你的第二个是。
  • 这能回答你的问题吗? C String Null Zero?
  • 要明确,如果我只声明一个字符数组,输出是正常的。只有当程序在 main() 中的任何位置声明第二个数组时,程序才会对第一个数组上的额外字符进行加扰。
  • @CrazyDiamond 仅使用一个数组时不打印垃圾的唯一原因是第一个数组后面的内存恰好是0s(可能是因为您正在使用调试进行编译标志?)。当您使用两个数组时,第二个数组在堆栈内存中跟随第一个数组,因此运行时无法判断第一个数组的结束位置和第二个数组的开始位置。

标签: c++ arrays char output cout


【解决方案1】:

总结 cmets 中的响应,在 C 中,“字符串”没有关联的长度。相反,它由一个尾随空字符表示的“字符串”的结尾,即0

当你使用初始化字符数组时

char text1[] = {'v', 'e', 'r', 'y'};

您创建了一个正好由四个字符组成的数组,no 尾随为空。如果您尝试将此“字符串”传递给需要尾随空分隔字符串的函数,例如std::cout::operator&lt;&lt;(const char*),您将产生未定义的行为,因为将读取字符串之后的任意内存,直到找到空字符。

在您的 cmets 示例中,仅使用一个数组时不打印垃圾的唯一原因是数组后面的内存恰好是 0s(可能是因为您正在使用调试标志进行编译?)。但是,当您使用两个数组时,第二个数组在堆栈内存中的第一个之后,因此cout::operator&lt;&lt; 无法分辨第一个结束和第二个开始的位置。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-26
    • 2013-12-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-18
    • 2011-03-06
    • 2011-07-12
    • 2013-10-22
    相关资源
    最近更新 更多