簡體   English   中英

為什么cout <<&r與cout <<(void *)&r給出不同的輸出?

[英]Why does cout << &r give different output than cout << (void*)&r?

這可能是一個愚蠢的問題,但是我是C ++的新手,所以我仍然在愚弄基本知識。 測試指針時,遇到了無法產生預期輸出的問題。

當我運行以下命令時:

char r ('m');
cout << r << endl;
cout << &r << endl;
cout << (void*)&r << endl;

我期望這樣:

m
0042FC0F
0042FC0F

..但是我得到了:

m
m╠╠╠╠ôNh│hⁿB
0042FC0F

我在想,也許因為r的類型為charcout會將&r解釋為char* ,[出於某種原因]輸出指針值-包含r的地址的字節-作為一系列chars ,但是為什么會這樣呢?第一個將是m ,即指向的地址的內容 ,而不是指針地址的第一個字節的char表示。.好像cout&r解釋為r而不是僅輸出'm' ,它繼續輸出更多字符-從隨后的11個存儲器地址的字節值解釋。為什么? 為什么11?

我在64位Win7上使用MSVC ++(Visual Studio 2013)。


附言:我在這里得到了很多正確答案(如預期的那樣,考慮到問題的瑣碎性質)。 由於我只能接受一個,因此我將其設為第一個看到的對象。 但是,謝謝大家。

因此,總結並擴展我的問題中提到的本能理論:

是的, cout確實將&r解釋為char* ,但由於char*是C ++中的“特殊事物”,從本質上講是指以空終止的字符串 (而不是指向單個char 的指針 ),因此cout會嘗試打印出該字符串通過輸出chars(從r的內存地址的字節內容開始解釋)直到遇到'\\0'為止。 這就解釋了11個額外的字符(恰好又花了11個字節才能擊中NUL )。

為了完整起見-相同的代碼,但是用int代替char ,按預期執行:

int s (3);
cout << s << endl;
cout << &s << endl;
cout << (void*)&s << endl;

產生:

3
002AF940
002AF940

對於char*字符串,有一個operator<<重載。 這將輸出以零結尾的字符串,而不是地址。 由於要傳遞此重載的指針不是以Null結尾的字符串,因此當operator<<越過緩沖區的末尾時,也會得到未定義的行為。

相反, void*重載將打印地址。

char *C++一種特殊東西,它繼承自C 在大多數情況下,它是C風格的字符串。 它應該指向以0 (NUL字符'\\0' )結尾的char數組。

因此,它嘗試打印此內容,然后在'm'之后繼續到內存中,尋找終止的'\\0' 這使其打印一些隨機垃圾。 這稱為未定義行為

因為有一個operator<<的重載,它使用const char指針作為第二個參數並輸出一個字符串。 帶有void指針的重載僅輸出地址。

因為operator<<根據數據類型被重載。

如果給它一個char ,它將假定您想要該字符。

如果給它一個void* ,則假定您要一個地址。

但是,如果給它一個char* ,它將把它作為C樣式的字符串並嘗試將其輸出。 由於C ++的原始意圖是“帶類的C”,因此必須處理C樣式的字符串。

最后得到所有垃圾的原因僅僅是因為盡管您對編譯器進行了斷言,但實際上它不是 C樣式的字符串。 具體來說,不能保證在結尾處有一個以字符串結尾的NUL字符,因此輸出例程將僅輸出其后在內存中發生的任何事情。

這可能會起作用(如果那里有一個NUL),它可能會打印出亂碼(如果附近有一個NUL),或者它可能會掉下來(如果在存儲到內存之前沒有NUL,則無法讀取)。 不是您應該依賴的東西。

char *通常(通常是偶數)是指向C樣式的以null終止的字符串(或字符串文字)的指針,並被ostream視為此類。 相反, void *明確表示需要一個指針值。

char const*void const*的輸出運算符( operator<<() )已重載。 當傳遞char*char const* char*的重載是更好的選擇。 此重載需要一個指向以空終止的字符串開頭的指針。 給它一個指向單個char的指針,即,您得到未定義的行為。

如果您想嘗試一個定義明確的示例,則可以使用

char s[] = { 'm', 0 };
std::cout << s[0] << '\n';
std::cout << &s[0] << '\n';
std::cout << static_cast<void*>(&s[0]) << '\n';

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM