在C++中,如果cout一個字符數組的話,那麼它會沿着這個地址,一直輸出這個字符串,直到遇到'\0',例如:
char*c="cadn\0hello";
cout<<c<<endl;
輸出的結果是:cadn
如果我們自作聰明的想輸出第一個字符的地址,例如這樣輸出:
cout<<&c[0]<<endl;
不幸的是,這樣輸出的結果依舊不是我們需要的地址。
但是,如果我們迴歸到C語言的話,例如用printf的話,如下:
printf("%x\n",&c[0]);
幸福的事情發生了,輸出的結果是:
46f020
的確是字符串的首地址,但是,如果我們要輸出字符串的地址,難道就這一種方法嗎?難道我們就不可以用我們C++上的cout達到我們的效果嗎?
原因:c是靠%s,%x,%p來區分指針表達式&a[0]的輸出形式的;c++沒有這個格式控制,只能按一種形式輸出,對char*類型的指針值就理解爲串輸出,所以必須對這個指針表達式做類型轉換處理。
例如:
char c='a';
cout<<” &c:”<<&c<<endl;
輸出的仍然不是字符變量c的地址。
在C++中,字符串是以空終止符('/0')結尾的字符數組,通過字符串中第一個字符的指針訪問字符串。也就是說,字符串的值是字符串中第一個字符的(常量)地址。如下的面3種形式表示:
char *str="string";
charstr2[]="string2";
charstr3[]={'s','t','r','i','n','g','3','/0'};
cout<<"line 1:str="<<str<<endl;
cout<<"line 2:str2="<<str2<<endl;
cout<<"line 3:str3="<<str3<<endl;
運行可知,這3行的輸出就是保存的字符串的值,而並非我們認爲的地址。那麼,我們可以聯繫到前面&c,其實這就是一個char *的變量,所以,輸出的自然就應該是字符串的值。可是,&c保存的字符串是沒有終止符的,因此輸出的也就是亂碼了。
最近,在讀到《C++程序設計教程》(第4版)第12章的時候,我才解決了這個疑惑。實際上,C++標準庫中I/O類對輸出操作符<<重載,在遇到字符型指針時會將其當做字符串名來處理,輸出指針所指的字符串。既然這樣,我們就別讓他知道那是字符型指針,所以得進行類型轉換,即:希望任何字符型的指針變量輸出爲地址的話,都要作一個轉換,即強制char *轉換成void *,如下所示:
cout<<"static_cast<void *>(&c)="<<static_cast<void*>(&c)<<endl;
cout<<"static_cast<void *>(str)="<<static_cast<void*>(str)<<endl;
此時,可以看到輸出的結果就是char類型變量和字符串變量的地址了。
轉自:http://blog.csdn.net/sszgg2006/article/details/7982866
-----------------------------------------------------------------------------------------------------------------------------------------------
C++中遇到字符型指針會將其當做字符串名來處理,但是對於string類指針,卻可以直接輸出指針的值,代碼如下:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str = "abc";
char *p = "abc";
cout << p << endl; //字符指針的值不能直接輸出
string * ps = new string(str);
cout << ps << endl; //字符串指針的值可以直接輸出
cout << *ps << endl;
str = * ps; //string類對=進行了重載,類似深拷貝,參數是string類對象,所以*ps就是一個string對象
delete ps;
cout << str << endl;
return 0;
}