理解char引用

10

我写了这个简单的脚本来理解什么是引用,但我卡在了字符数组上。

int numbers[5] = {3, 6, 9, 12, 15};

for (int i = 0; i < 5; i++)
{
    cout << numbers[i] << endl;
    cout << &numbers[i] << endl;
}

cout << "--------------" << endl;

char letters[5] = {'a', 'b', 'c', 'd', 'e'};

for (int i = 0; i < 5; i++)
{
    cout << letters[i] << endl;
    cout << &letters[i] << endl;
}

这是输出结果:

3
0xbffff958
6
0xbffff95c
9
0xbffff960
12
0xbffff964
15
0xbffff968
--------------
a
abcde
b
bcde
c
cde
d
de
e

使用int数组时,当我使用&numbers[i]时,我会收到一个奇怪的数字,它是一个内存位置。这没关系;这正是我理解的。

但是对于char,我不明白为什么会有这样的输出。


1
我有点惊讶第二部分没有彻底崩溃,因为根据代码所说,“letters”并没有以空字符结尾。但是,UB确实意味着“任何事情都可能发生,即使程序表面上看起来正常运行”。 - cHao
2
@cHao:一些编译器在调试模式下编译时会将许多内容初始化为零。也许楼主很“幸运”。 - André Caron
1
我很惊讶还没有人提到这一点,但这与引用无关。你正在谈论指针。 - Andreas Bonini
3个回答

13

原因在于 cout 知道如何对待一个 char * 值 - 它将打印以 NUL 结尾的 C 字符串。

对于 int * 值,情况并非如此,因此 cout 打印指针值。

你可以通过进行强制类型转换来强制输出指针值:

cout << static_cast<void *>(&letters[i]) << endl;

2

您正在查看 C++ 流的一种奇特之处。它会尝试将其参数转换为通常可以打印的东西。这个表达式的类型是 &ints[x] int*&chars[x] 变成了 char*,顺便提一下,这也是 C 字符串的类型。由于我们想要 cout << "FOO"' 打印出整个字符串,因此需要这种行为。在您的情况下,实际上会导致未定义的行为,因为您使用的字符串没有正确的空终止符。要解决此问题,请使用 static_cast


2
当您将类型为char*的参数传递给ostream::operator<<(实际上它是一个全局函数,而不是运算符)时,它被视为一个以null结尾的字符串。

我不认为标准规定必须是ASCII。 - Matti Virkkunen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接