2011-11-25 170 views
4

是什么低于int和字符数组的区别:int和char数组有什么区别?

int main() 
{ 
    int numbers[] = {2,1,3}; 
    char letter[] = {'a','b','\0'}; 
    cout<< numbers<<endl; 
    cout<< letter<<endl; 
} 

输出:

0x22ff12 // an address 
ab 

为什么不是213显示? 我知道一个数组的名称将指向它的第一个元素的地址,但为什么 做一个字符数组显示不同的行为?

+4

在C中,阵列衰变成指针到他们的第一元件在大多数情况下...但'cout'和'<<'和'endl'是C语言中无法识别的元素。 – pmg

+0

呃...我的意思是:C中的'<<'是左移运算符,不能用于无法识别的语言元素:) – pmg

回答

8

没有operator<<重载需要阵列,准确,所以你传递参数(例如numbersletter)经历阵列到指针转换,void*char*分别。

有一个operator<<()超载需要const void*,另一个需要const char*。当您拨打:

cout<< numbers<<endl; 

const void*版本匹配,但是当你拨打:

cout<< letter<<endl; 

const char*版本匹配。

const void*版本中,会显示指针,而const char*版本会将字符串显示为空终止符。

+0

@dlev:感谢您的编辑。 –

+1

阅读其他答案,因为它们是真的。 –

1

在C/C++中,数组实际上是指向第一个元素的指针。指针保存存储值的地址。因此,如果您打印指针编号,您将获得第一个值(2)存储在内存中的地址。

char *是一个例外,因为它会在您尝试打印时表现为字符串。

+2

数组不是指针;他们*衰减*在许多情况下的指针,但这并不能使它们成为同一事物。 – dlev

7

当您使用cout打印数组时,它将打印数组的基地址。

异常与已被重载的字符数组打印为c字符串。

如果您想要打印int数组的元素,则需要逐个元素执行此操作。

+0

为什么downvote?我的回答有问题吗? – Mysticial

3

char数组是特殊的,因为操作符< <有一个过载,将内容显示为字符串。

所有其他阵列默认都会显示地址。

+0

谢谢你的回答是正确的。 –

0

数字是一个指针。 C++中的所有数组实际上都是指针,数字[3]意味着“内存地址&数字+3的值”,所以您输出数字中第一个元素的内存地址。

4

在C中,因此在C++中,一个字符串通常由以0结尾的字符数组表示。因此,为std :: ostream类提供了一个重载运算符< <,其中std :: cout是一个将char *作为字符串打印的实例。 int数组没有这种常见用法,也没有任何约定,所以操作员会'知道'要输出多少个元素,所以指向数组的指针与运算符< <的版本相匹配,通过打印其地址输出任何其他指针。

+0

+1,因为这是我想写的。但是我认为如果你能够展示这两种重载的具体函数原型,这将是教育性的(=有用)。 –

1

你的代码主要是指C语言。一个char的数组实际上是C中字符串的表示形式。另一方面,C中的数组也是指向存储单元的指针(单元的地址)数组的第一个元素。

所以,当你打印出一个字符数组时,你实际上会打印出一个字符串(因为C会这样处理它)。当你打印一个整数数组时,你打印出数组第一个元素的地址。

0

没有理由编译器应该知道你的int[]数组结束的位置,但传统和标准库规定C字符串以NULL结尾char[]数组。没有这种传统或库支持零终止int[]阵列。

如果您需要此功能,可以使用C++ pretty打印机templates。我隐约记得,当类型实际知道边界时,我们会使用数组的边界,即由于您使用的是[]而不是[3],所以您的代码仍然不起作用。

Just fyi,你的代码不能通过在STL内部用[3]代替[]来修复,尽管operator<<可能会被重载。

+0

使用模板参数的C数组边界时需要注意:http://publib.boulder.ibm.com/infocenter/lnxpcomp/v7v91/index.jsp?topic=%2Fcom.ibm.vacpp7l.doc%2Flanguage% 2Fref%2Fclrc16deduct_non-type.htm –

4

原因是operator<<超载为const char*,它打印每个字符,直到遇到\0

没有这样的过载对应于int[N],它打印每个元素。相反,当您编写cout << numbers时,它会调用operator<<,该文件超载为void*,并打印该地址。

但是,如果您将operator<<重载为T[N],那么您也可以像那样打印它。

下面是一个简单的例子:

template<typename T, size_t N> 
std::ostream & operator<<(std::ostream & out, const T (&a)[N]) 
{ 
    for(size_t i = 0 ; i < N ; ++i) 
     out << a[i] << ' '; 
    return out; 
} 

int main() 
{ 
    int numbers[] = {2,1,3}; 
    char letter[] = {'a','b','\0'}; 
    cout<< numbers<<endl; 
    cout<< letter<<endl; 
} 

输出:

2 1 3 
a b 

演示:http://ideone.com/O4T9N

+1

+1惊讶没有投票已经。显示为什么以及如何。 –

相关问题