2017-07-11 97 views
0

爲什麼這個程序不能打印出「hello」?當我取消註釋循環內部的行時,它可以工作。我想知道爲什麼字符串值沒有被存儲的概念。謝謝!存儲一個字符串並打印出來

#include<iostream> 

using namespace std; 

void reverse(string str) { 
     int length = str.length(); 
     int x = length, i = 0; 
     string newString; 

     while(x >= 0) { 
       newString[i] = str[x-1]; 
       //cout << newString[i]; 
       x--; 
       i++; 
     } 

     cout << newString; 
} 

int main() { 
     reverse("hello"); 

return 0; 
} 
+1

使用調試器的時間。它應該可以幫助你很快找出發生的事情。 – aschepler

+0

查看C++中[]運算符的參考頁。它作爲一個getter,而不是setter http://www.cplusplus.com/reference/string/string/operator[]/ –

+1

恐怕這不完全正確,@Cole。 '[]'返回一個引用,允許它執行雙重任務。假設'string'不是常量,那就是。 – user4581301

回答

5

newString的大小爲0(默認構造函數構造的),所以寫過去的結束它與newString[i] = ...會導致不確定的行爲。使用.resize在寫入字符串之前調整字符串的大小(使其足夠大)

2

該程序有幾個問題。

對於初學者來說,你應該包含頭<string>

#include <string> 

因爲節目從這個標題上使用的聲明。這是沒有必要的頭<iostream>包括頭<string>

這是更好的聲明像

void reverse(const string &str); 
每次

否則,將創建作爲參數原始字符串的副本功能,當功能調用。

對於大小類型,類std::string定義了自己的無符號整數類型,名稱爲size_type。最好使用它或類型說明符auto而不是int

本聲明

string newString; 

newString後是空的。所以你可能不會使用下標操作符。您應該調整字符串大小或爲字符串添加新元素預留足夠的內存。

考慮到這一點,可以通過以下方式定義函數。

#include <iostream> 
#include <string> 

using namespace std; 

void reverse(const string &str) { 
     auto length = str.length(); 
     string newString; 
     newString.reserve(length); 

     for (auto i = length; i-- != 0; ) newString += str[i]; 

     cout << newString << endl; 
} 

int main() { 
     reverse("hello"); 

     return 0; 
} 

考慮到這些功能可能會基於類std::string本身的功能來定義簡單。例如

#include <iostream> 
#include <string> 

using namespace std; 

void reverse(const string &str) { 
     string newString(str.rbegin(), str.rend()); 

     cout << newString << endl; 
} 

int main() { 
     reverse("hello"); 

     return 0; 
} 
+0

你能向我解釋一下使用「const string&str」多一點的理由嗎?謝謝。 – aashman

+0

@aashman這裏使用了對原始字符串的引用,它既不是創建原始字符串的副本,也是在程序中每次調用該函數時創建原始字符串的副本。這是資源消耗。 –

相關問題