2012-02-12 47 views
10

我已经写了这个简单的脚本来理解引用是什么,并且我陷入了char数组。了解字符引用

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

我感到半惊讶第二部分并没有打破所有的地狱和背部,考虑到代码说''字母'不是终止。但是,UB的确意味着“任何事情都可能发生,甚至程序显然也在工作”。 – cHao 2012-02-12 23:50:39

+2

@cHao:在调试模式下编译时,一些编译器会将许多东西初始化为零。也许OP是“幸运的”。 – 2012-02-12 23:52:33

+1

我很惊讶没有人提到过这一点,但这与参考文献无关。你在谈论指针。 – 2012-02-13 00:24:10

回答

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"'打印出整个字符串,所以需要这种行为。在你的情况下,这实际上导致了未定义的行为,因为你使用的字符串没有正确的以null结尾。要解决此问题,请使用static_cast

2

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

+0

我没有标准规定它必须是ASCII。 – 2012-02-12 23:52:40

+0

@MattiVirkkunen谢谢! – 2012-02-12 23:55:50