2016-10-22 57 views
-1

我寫了一個程序來使用指針交換兩個字符串。使用指針交換兩個字符串打印奇怪的輸出

char *names[]={"Sachin","Kapil","Ajay","Sunil","Anil"}; 
cout<<"String II is ";cout<<names[1]; 
cout<<"\nString IV is ";cout<<names[3]; 
char *t; 
t=names[1]; 
names[1]=names[3]; 
names[3]=t; 
cout<<"\nString II is ";cout<<names[1]; 
cout<<"\nString IV is ";cout<<names[3]; 

在第一行中我用炭指針數組以存儲串的第一字符的地址。

當我cout的名稱[1]和名稱[3]:

整個字符串印刷,但不應單獨的字符指針的地址被打印?

此外,程序如何打印整個字符串而不是單獨打印第一個字符?

編譯後,我收到第1行的警告: 警告:不推薦將字符串常量轉換爲'char *'[-Wwrite-strings] |

該程序按預期運行,但我很想知道它是如何工作的。我遇到了一個實現,他們使用cout.write(names [i],len)打印整個字符串(這很有意義) ,但令我驚訝的是,上述方法也可以工作(即使沒有任何增加指針值來打印下一個字符)。

有關上述問題的任何提示和建議,將不勝感激。謝謝!

+0

它必須將'char * names []'分解爲兩個塊。 'char *'和'names []'是一個名爲char指針的數組。 –

回答

0

首先 - 爲什麼你不只是得到地址輸出。 當您將任何char*插入流中時,例如std::cout<<s;其中s的類型爲char*插入邏輯假定s指向'C'字符串的第一個字符。 'C'字符串是一系列以nul結尾的字符('\0'字符)。 因此,插入邏輯輸出該系列字符。

如果您使用std::cout<<static_cast<void*>(c);,則會得到不同的結果,因爲插入的void*指針的處理方式不同。

流上的<<運算符被重載,根據你所插入的內容做不同的事情。

現在你爲什麼得到這個警告。你發現了一些不幸的遺留C++特別是從C繼承的行李。 在C早期的舊版本中,如果沒有const修飾符,那麼就沒有辦法指出字符串文字(例如「Sachin」)不能修改在運行時以及不同的平臺上執行此操作時會產生不同的影響,從修改數據的無害修改,拋出訪問異常以修改代碼中所有字面引用的字符串值(可能有多個)。

所以當C++出現並引入了const(很快被C採納)時,很適合在代碼const char[]中生成字符串文字的類型。但是,有些編譯器(如果您的設置錯誤!)仍然允許您將文字分配到char[](或char*)以實現向後兼容。 除非你維護古代代碼,並且高級程序員已經指示你,否則不要啓用該選項。

0

流庫識別char *類型並將其視爲空終止的c樣式字符串,它只是由null終止的字符數組。

要將它打印到打印地址,請將字符串類型轉換爲void *。

cout << "String II is "; cout << (void *)names[1]; 

現在將輸出:

String II is 0x400a0b 

至於爲什麼不僅印刷在第一字符,這是因爲該流庫把它當作空結尾的C字符串。但如果你真的只想要第一個字符打印,你可以很容易地做到了這一點:

cout << "String II is "; cout << *names[1]; 

或:

cout << "String II is "; cout << names[1][0]; 

操縱指針像你這樣是好的,但操作所包含的內容是不是當宣佈就像你有他們一樣。所以你應該真的把它們聲明爲const。這也刪除了編譯警告。 所以代碼會變成。

const char *names[]={"Sachin","Kapil","Ajay","Sunil","Anil"}; 
cout << "\nString II is "; cout << (void*)names[1]; 
cout << "\nString IV is "; cout << (void*)names[3]; 

const char *t; 
t = names[1]; 
names[1] = names[3]; 
names[3] = t; 

cout << "\nString II is "; cout <<(void*)names[1]; 
cout << "\nString IV is "; cout <<(void*)names[3]; 
+1

'endl'事情不正確,'endl'只是強制實際上會損害性能的flush。使用'\ n'很好,實際上是推薦的方法。我會補充說,如果你不想緩衝,比使用'\ n'更好的方法是簡單地使用'cerr'而不是'cout'。 –

+0

感謝您澄清@NirFriedman。我不知道這是因爲我討厭iostream庫,很少親自使用它。 – Matt

相關問題