#include <string> using std::string;
#include <iostream> using std::string; int main() { string s1 = "hello"; string s2 = "world"; std::cout<<s1+s2<<std::endl; return 0; }
string的初始化:ios
string s1; //默認初始化 string s2(s1); string s2 = s1; string s3("value"); string s3 = "value"; string s4(n, 'c'); //用n個'c'來初始化字符串
初始化分爲兩種:1.複製初始化(copy initialization) 2.直接初始化(direct initialization)c++
os << s //如cout<<s is >> s //如cin>>s getline(is, s) //如getline(cin, s) s.empty() s.size() //返回類型是string::size_type,具體是unsigned,足夠大 s[n] s1+s2 //字符串鏈接 s1,s2比較 //如s1==s2,s1!=s2,s1<s2
int main() { string s; cin >> s; cout<< s <<endl; /*忽略前面的whitespace(如空格、換行、tabs),直到再次遇到whitespace爲止 如:鍵入[ hello world ],輸出[hello] */ string line; getline(cin, line); cout << line <<endl; /*不忽略whitespace,獲得一整行,可是不包括換行符。 如:鍵入[ hello world ],輸出[ hello world ] */ return 0; }
int main() { string word; while(cin>>word) { cout<<word<<endl; } /*打印文件中所有的單詞,直到end-of-file結束(EOF)。在C語言中while(scanf("%s", word)!=EOF) 測試經常使用重定向符:./a.out < data.txt */ string line; while(getline(cin, line)) { cout<<line<<endl; } /*打印文件中所有的行,直到end-of-file結束(EOF)。在C語言中while(scanf("%s", word)!=EOF) 測試經常使用重定向符:./a.out < data.txt */ return 0; }
在C++11中,能夠用auto關鍵字來推斷size()的返回值:編程
auto len = line.size(); //len is type string::size_type
string s1 = "hello", s2 = "world"; string s3 = s1 + ", " + s2; //ok string s4 = s1 + ", "; //ok:adding a string and a literal string s5 = "hello"+", "; //error:no string operand
C++11中最好的方式是range for表述。數組
string str("some string"); for(auto c : str) //實際上是char,用char也能夠 cout<<c<<endl;
#include<iostream> using namespace std; int main() { //將s轉換成大寫字符串 string s = "hello, world"; for(auto &c : s) //引用 c = toupper(c); cout<<s<<endl; //output: HELLO,WORLD return 0; }
#include<vector> using std::vector;
#include<iostream> #include<stdexcept> using namespace std; int main() { int a,b; cin>>a>>b; if(a!=b) throw runtime_error("not same"); else ..... }
拋出異常將終止當前的函數,並把控制權轉移給能處理該異常的代碼。app
類型runtime_error是標準庫異常類型的一種,定義在stdexcept頭文件中。函數
函數的參數傳遞在C++中只有兩種:值傳遞和引用傳遞。傳遞指針其實也是值傳遞(拷貝進函數內的是指針的副本)。引用傳遞是對象自己,使用引用能夠避免拷貝。特別是一些複雜的類型。測試
bool isShorter(const string &s1, const string &s2) { return s1.size()<s2.size(); }
另外,使用引用形參還能夠返回額外信息。這是常見的編程技巧,由於一個函數只能返回一個值,然而有時函數須要同時返回多個值,引用形參爲咱們一次返回多個結果提供了有效的途徑。spa
使用標準庫規範指針
void print(const int *beg, const int *end) { while(beg!=end) cout<< *beg++ <<endl; } int j[2]={0,1}; print(begin(j), end(j));
顯式傳遞一個表示數組大小的形參調試
這個方法很經常使用。
void print(const int[], size_t size);
這塊用的很少,可是也要理解。C++容許將變量定義成數組的引用。
/* **這裏[10]個數必須去肯定的,不然出錯 **注意:只有引用才能夠用這種for語句,不然出錯。如在void print(const int arr[], size_t n)中使用for(auto elem : arr)將會報錯,由於不知道數組具體的大小。 */ void print(int (&arr)[10]) { for(auto elem : arr) cout<<elem<<endl; }
無返回值函數能夠有沒有返回值的return語句。
const string &manip() { string ret; if(!ret.empty()) return ret; else return "Empty"; }
上面的兩條return語句都將返回未定義的值,也就是說,試圖使用manip函數的返回值將引起未定義的行爲。對於第一條return語句來講,顯然返回的是局部對象的引用。在第二條return語句中,字符串字面值轉換成一個局部臨時string對象,對於manip來講,該對象和ret同樣都是局部的。
函數的返回類型決定函數調用是不是左值。調用一個返回引用的函數獲得左值,其餘返回類型獲得右值。能夠像使用其餘左值那樣來使用返回引用的函數的調用,特別是,咱們能爲返回類型是很是量引用的函數的結果賦值:
char &get_val(string &str, string::size_type ix) { return str[ix]; } int main() { string s("a value"); cout<< s << endl; get_val(s, 0) = 'A'; cout<< s << endl; return 0; }
把函數調用放在賦值語句的左側可能看起來有點奇怪,但其實這沒什麼特別的。
vector<string> process() { //expected和actual是string對象 if(expected.empty()) return {}; else if(expected==actual) return {"functionX", "okay"}; else return {"functionX", expected, actual}; }
assert是一種預處理宏。所謂預處理宏實際上是一個預處理變量,它的行爲有點相似於內聯函數。assert宏使用一個表達式做爲它的條件:assert(expr);
首先對expr求值,若是表達式爲假,assert輸出信息並終止程序的執行。若是表達式爲真,assert什麼也不作。
assert宏定義在cassert頭文件中。
vector 可變大小數組 deque 雙端隊列 list 雙向鏈表 forward_list 單向鏈表 array 固定大小數組 string 與vector類似的容器,但專門用於保存字符。隨機訪問快。
forward_list和array是新C++11標準增長的類型。通常來講,每一個容器都定義在一個頭文件中,文件名與類型名相同。即,deque定義在頭文件deque中,list定義在頭文件list中,依次類推。容器均定義爲模板類。例如對vector,咱們必須提供額外信息來生成特定的容器類型。如:
list<Sales_data> deque<double>
標準庫array具備固定大小
與內置數組同樣,標準庫array的大小也有類型的一部分。當定義一個array時,除了指定元素的類型,還要指定容器大小。如:
array<int, 42> //類型爲:保存42個int的數組 array<string, 10> //類型爲:保存10個string的數組
爲了使用array類型,咱們必須同時指定元素類型和大小:
array<int, 10>::size_type i; //ok array<int>::size_type j; //error
c++內置了swap函數,能夠交換相同類型的對象。如:
#include<iostream> #include<vector> using namespace std; int main() { int m=5,n=6; swap(m,n); //交換兩個整數 cout<<m<<n<<endl; vector<int> v1, v2; v1.push_back(1); v1.push_back(2); v2.push_back(3); v2.push_back(4); swap(v1, v2); //交換兩個vector return 0; }
因爲string是一個字符容器,咱們也能夠用push_back在string末尾添加字符(這個之前真不知道):
void pluralize(size_t cnt, string &word) { if(cnt>1) word.push_back('s'); }
string類型支持順序容器的賦值運算符以及assign、insert和erase操做。
s.insert(s.size(), 5, '!'); //在s末尾插入5個感嘆號 s.erase(s.size()-5, 5); //從s刪除最後5個字符 const char *cp = "Stately, plump Buck"; s.assign(cp, 7); //s=="Stately" s.insert(s.size(), cp+7); //s=="Stately, plump Buck" string s1 = s.substr(0,7); //s1=="Stately" s.append("."); s.replace(5,3,"5th");