2011-11-25 321 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驚訝沒有投票已經。顯示爲什麼以及如何。 –

相關問題