带输出的极其简单的代码,我听不懂...
#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�>��
奇怪
每次输出为'very'时,第二个数组中的字符数相同。如果我将第一行更改为
,则此输出正确char text1[] = "very";
或者如果我不声明并引用第二个数组。
必须与用{'',``,'',...}初始化char的方式有关。我注意到在这种情况下sizeof(text1)为4,在使用char text1 [] =“非常”;sizeof(text1)为5,最后一个位置留为空白。当声明第二个字符时,第一个字符的sizeof仍然是准确的,但是第二个字符位于内存中第一个字符之后的位置。
如果我这样重写程序...
int main() {
char text1[] = {'v', 'e', 'r', 'y'};
char text2[] = "strange";
cout << text1 << endl;
cout << text2 << endl;
return 0;
}
输出变为:
verystrange
strange
似乎,如果我声明更多的char数组,它总是将最后一个字符滑入第一个字符数组(text1 [])之后,并在内存中向前冲动其他字符以腾出空间。仅在使用{}时发生;初始化。真的只是想知道这里发生了什么...我看不到这会在编写良好的程序中引起任何问题。
为了总结注释中的响应,在C中,“字符串”没有关联的长度。而是以结尾的空字符表示的“字符串”的末尾,即0
。
使用初始化字符数组时
char text1[] = {'v', 'e', 'r', 'y'};
您创建了一个精确的四个字符的数组,并以no尾随null。如果尝试将此“字符串”传递给需要以空分隔的字符串的函数,例如std::cout::operator<<(const char*)
,则将产生未定义的行为,因为将读取该字符串之后的任意内存,直到找到空字符为止。
在您的第一个示例中,仅使用一个数组时不打印垃圾的唯一原因是,第一个数组之后的内存恰好是0
s(也许因为您正在使用调试标志进行编译?) 。但是,当您使用两个数组时,第二个数组紧随堆栈中的第一个数组,因此运行时无法确定第一个数组的结尾和第二个数组的起点