1. 名稱空間using namespace std的解釋
//區分不同庫中相同名稱的函數、類、變量等。本質上,命名空間就是定義了一個范圍。 //std是一個命名空間,C++標准函數或者對象都是在std中定義的,例如cin和cout,當我們要使用標准庫的函數或對象時都需要用std來限定。
2. cin和cout輸入輸出
<iostream> //該文件定義了 cin、cout、cerr 和 clog 對象,分別對應於標准輸入流、標准輸出流、非緩沖標准錯誤流和緩沖標准錯誤流。
3. 關於C++的頭文件
#include <algorithm> //STL通用算法 #include <bitset> //STL位集容器 #include <deque> //STL雙端隊列容器 #include <functional> //STL定義運算函數(代替運算符) #include <list> //STL線性列表容器 #include <map> //STL 映射容器 #include <queue> //STL隊列容器 #include <set> //STL 集合容器 #include <stack> //STL堆棧容器 #include <utility> //STL通用模板類 #include <vector> //STL動態數組容器 #include <cmath> #include <complex> //復數類 #include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> #include <exception> //異常處理類 #include <limits> #include <ios> //基本輸入/輸出支持 #include<iosfwd> //輸入/輸出系統使用的前置聲明 #include <iostream> #include <istream> //基本輸入流 #include <ostream> //基本輸出流 #include <sstream> //基於字符串的流 #include <stdexcept> //標准異常類 #include <string> //字符串類
4. C++特有的bool變量
//bool 變量有兩個值, false 和 true //C++把所有⾮零值解釋為 true ,零值解 釋為 false bool flag = true; bool flag2 = -2;//flag2為true bool flag3 = 0;//flag3為false
5. const定義常量
//C++⾥⾯⽤ const 這個限定符定義常量,這樣做有個好處 就是可以定義常量的類型,⽐如 int 類型的常量 a 這樣定義: const int a = 99999999;
6. string類
6.1 字符串函數
//C++中用來操作以null結尾的字符串函數 strcpy(s1, s2);//復制字符串 s2 到字符串 s1。 strcat(s1, s2);//連接字符串 s2 到字符串 s1 的末尾。連接字符串也可以用 + 號 strlen(s1);//返回字符串 s1 的長度。 strcmp(s1, s2);//如果 s1 和 s2 是相同的,則返回 0;如果 s1<s2 則返回值小於 0;如果 s1>s2 則返回值大於 0。 strchr(s1, ch);//返回一個指針,指向字符串 s1 中字符 ch 的第一次出現的位置。 strstr(s1, s2);//返回一個指針,指向字符串 s1 中字符串 s2 的第一次出現的位置。
6.2 字符串類
#include <iostream> #include <string> using namespace std; int main () { string str1 = "runoob"; string str2 = "google"; string str3; int len ; // 復制 str1 到 str3 str3 = str1; cout << "str3 : " << str3 << endl; // 連接 str1 和 str2 str3 = str1 + str2; cout << "str1 + str2 : " << str3 << endl; // 連接后,str3 的總長度 len = str3.size(); cout << "str3.size() : " << len << endl; return 0; }
6.3 字符串替換
//C++字符串替換,string類的 replace(起始位置,長度,替換成的字符串); #include <iostream> using namespace std; int main() { string str1 = "I love C++"; string newStr = str1.replace(2, 4, "LIKE"); cout << "str1 = " << str1 << endl; cout << "newStr = " << newStr << endl; } /* str1 = I LIKE C++ newStr = I LIKE C++ */ //迭代器進行字符串替換 string newStr = str1.replace(str1.begin(), str1.begin()+6, "LIKE"); /* str1 = I LIKE C++ newStr = I LIKE C++ */ //使用#include<algorithm>中的replace算法 #include <algorithm> #include <string> #include <iostream> using namespace std; int main() { string str = "123/456/789"; cout << str <<endl; replace (str.begin(), str.end(), '/', ' ');//只能對單個字符進行操作
cout << str ;
return 0; } /* 123 456 789 */
7. C++的結構體struct和C語言的結構體區別
//定義結構 struct Books { char title[50]; char author[50]; char subject[100]; int book_id; } book; //訪問結構成員 Books Book1; // 定義結構體類型 Books 的變量 Book1 strcpy( Book1.title, "C++ 教程"); // 輸出 Book1 信息 cout << "第一本書標題 : " << Book1.title <<endl; //結構作為函數參數 printBook( Book1 );// 輸出 Book1 信息 void printBook( struct Books book ) { cout << "書標題 : " << book.title <<endl; } //指向結構的指針 struct Books *struct_pointer; struct_pointer = &Book1;//在上述定義的指針變量中存儲結構變量的地址。 struct_pointer->title;//指針訪問結構的成員 // 該函數以結構指針作為參數 void printBook( struct Books *book ) { cout << "書標題 : " << book->title <<endl; } // 通過傳 Book1 的地址來輸出 Book1 信息 printBook( &Book1 ); //typedef 關鍵字 typedef struct Books { char title[50]; char author[50]; char subject[100]; int book_id; }Books; Books Book1, Book2; //使用 typedef 關鍵字來定義非結構類型 typedef long int *pint32; pint32 x, y, z;//x, y 和 z 都是指向長整型 long int 的指針。
8. C++的引用&和傳值的區別
8.1 lambda表達式
//以lambda表達式為例 //Lambda 表達式把函數看作對象。Lambda 表達式可以像對象一樣使用,比如可以將它們賦給變量和作為參數傳遞,還可以像函數一樣對其求值。 //Lambda 表達式本質上與函數聲明非常類似。 [](int x, int y){ return x < y ; } //[capture](parameters){body} // 與JavaScript閉包不同,C++變量傳遞有傳值和傳引用的區別。可以通過前面的[]來指定: [] // 沒有定義任何變量。使用未定義變量會引發錯誤。 [x, &y] // x以傳值方式傳入(默認),y以引用方式傳入。 [&] // 任何被使用到的外部變量都隱式地以引用方式加以引用。 [=] // 任何被使用到的外部變量都隱式地以傳值方式加以引用。 [&, x] // x顯式地以傳值方式加以引用。其余變量以引用方式加以引用。 [=, &z] // z顯式地以引用方式加以引用。其余變量以傳值方式加以引用。 //另外有一點需要注意。對於[=]或[&]的形式,lambda 表達式可以直接使用 this 指針。但是,對於[]的形式,如果要使用 this 指針,必須顯式傳入: [this]() { this->someFunc(); }();
8.2 引用VS指針
//主要區別: //不存在空引用。引用必須連接到一塊合法的內存。 //一旦引用被初始化為一個對象,就不能被指向到另一個對象。指針可以在任何時候指向到另一個對象。 //引用必須在創建時被初始化。指針可以在任何時間被初始化。 //引用通常用於函數參數列表和函數返回值。 #include <iostream> using namespace std; // 函數聲明 void swap(int& x, int& y); int main () { // 局部變量聲明 int a = 100; int b = 200; cout << "交換前,a 的值:" << a << endl; cout << "交換前,b 的值:" << b << endl; /* 調用函數來交換值 */ swap(a, b); cout << "交換后,a 的值:" << a << endl; cout << "交換后,b 的值:" << b << endl; return 0; } // 函數定義 void swap(int& x, int& y) { int temp; temp = x; /* 保存地址 x 的值 */ x = y; /* 把 y 賦值給 x */ y = temp; /* 把 x 賦值給 y */ return; }
//當函數返回一個引用時,則返回一個指向返回值的隱式指針。這樣,函數就可以放在賦值語句的左邊 #include <iostream> using namespace std; double vals[] = {10.1, 12.6, 33.1, 24.1, 50.0}; double& setValues(int i) { double& ref = vals[i]; return ref; // 返回第 i 個元素的引用,ref 是一個引用變量,ref 引用 vals[i],最后再返回 shit。 } // 要調用上面定義函數的主函數 int main () { cout << "改變前的值" << endl; for ( int i = 0; i < 5; i++ ) { cout << "vals[" << i << "] = "; cout << vals[i] << endl; } setValues(1) = 20.23; // 改變第 2 個元素 setValues(3) = 70.8; // 改變第 4 個元素 cout << "改變后的值" << endl; for ( int i = 0; i < 5; i++ ) { cout << "vals[" << i << "] = "; cout << vals[i] << endl; } return 0; }
9. STL(標准模板庫)之動態數組vector(矢量)的使用
//向量容器(vector)與數組相似,不同的是,向量在擴展大小的時候,會自動處理它自己的存儲需求 //常用函數 //push_back( ) 成員函數在向量的末尾插入值,如果有必要會擴展向量的大小。 //size( ) 函數顯示向量的大小。 //begin( ) 函數返回一個指向向量開頭的迭代器。 //end( ) 函數返回一個指向向量末尾的迭代器。
#include <iostream> #include <vector> using namespace std; int main() { // 創建一個向量存儲 int vector<int> vec; int i; // 顯示 vec 的原始大小 cout << "vector size = " << vec.size() << endl; // 推入 5 個值到向量中 for(i = 0; i < 5; i++){ vec.push_back(i); } // 顯示 vec 擴展后的大小 cout << "extended vector size = " << vec.size() << endl; // 訪問向量中的 5 個值 for(i = 0; i < 5; i++){ cout << "value of vec [" << i << "] = " << vec[i] << endl; } // 使用迭代器 iterator 訪問值 vector<int>::iterator v = vec.begin(); while( v != vec.end()) { cout << "value of v = " << *v << endl; v++; } return 0; }
10. STL之集合set的使用
#include <iostream> #include <set> using namespace std; int main() { set<int> s; //定義一個空集合 s.insert(1); //向集合s里面插入一個1 cout << *(s.begin()) << endl; //輸出集合s的第一個元素(前面的星號表示要對指針取值) for (int i = 0; i < 6; i++) { s.insert(i); // 向集合s里面插入i } for (auto it = s.begin(); it != s.end(); it++) //用迭代器遍歷集合s里面的每一個元素 { cout << *it << " "; } cout << endl << (s.find(2) != s.end()) << endl; /*s.find(2)找二找到了會返回這個集合里面2所在的位置,里面是一個邏輯判斷,會和后面s.end()這個位置判斷,這兩個位置不相等就返回一,它返回1,就意味着這個集合的最后一個元素不是2*/ cout << (s.find(10) != s.end()) << endl; s.erase(1);// 刪除集合s中的1這個元素 cout << (s.find(1) != s.end()) << endl; return 0; }
11. STL之映射map使用
//判斷key是否存在 //if (map.count(key)) flag = 1; //else flag = 0; #include <iostream> #include <map> #include <string> using namespace std; int main() { map<string, int> m; // 定義⼀一個空的map m,鍵是string類型的,值是int類型的 m["hello"] = 2; // 將key為"hello", value為2的鍵值對(key-value)存⼊入map中 cout << m["hello"] << endl; // 訪問map中key為"hello"的value, 如果key不不存在,則返回0 cout << m["world"] << endl; m["world"] = 3; // 將"world"鍵對應的值修改為3 m[","] = 1; // 設⽴立⼀一組鍵值對,鍵為"," 值為1 // ⽤用迭代器器遍歷,輸出map中所有的元素,鍵⽤用it->first獲取,值⽤用it->second獲取 for (auto it = m.begin(); it != m.end(); it++) { cout << it->first << " " << it->second << endl; } // 訪問map的第⼀一個元素,輸出它的鍵和值 cout << m.begin()->first << " " << m.begin()->second << endl; // 訪問map的最后⼀一個元素,輸出它的鍵和值 cout << m.rbegin()->first << " " << m.rbegin()->second << endl; // 輸出map的元素個數 cout << m.size() << endl; return 0; }
12. STL之棧stack的使用
#include<iostream> #include<stack> using namespace std; int main() { stack<int> s; //定義一個空棧s for (int i = 0; i < 6; i++) { s.push(i);//將元素i壓入棧中 } cout << s.top() << endl;//訪問s的棧頂元素 cout << s.size() << endl;//輸出s的元素個數 s.pop();//移除棧頂元素 return 0; }
13. STL之隊列queue的使用
#include <queue> queue<int>q;//普通聲明 struct node{//聲明結構體 int x, y; }; queue<node>q; //基本操作 push(x) //將x壓入隊列的末端 pop()//彈出隊列的第一個元素(隊頂元素),注意此函數並不返回任何值 front()//返回第一個元素(隊頂元素) back()//返回最后被壓入的元素(隊尾元素) empty()//當隊列為空時,返回true size()//返回隊列的長度
14. STL之unordered_map和unordered_set的使用
//unordered_map 在頭文件 #include <unordered_map> 中, //unordered_set 在頭文件 #include<unordered_set> 中。 //unordered_map 和 map 的區別,用法,注意事項: map:map會按鍵值對的鍵key進行排序;如果偶爾刷題時候用map超時了,可以考慮用unordered_map提高代碼效率 unordered_map:省去了這個排序的過程 //unordered_set 和 set 的區別,用法,注意事項: set:set里面會按照集合中的元素大小進行排序,從大到小順序,如果刷題則可以使用unordered_set提高代碼效率 unordered_set:省去了排序過程
15. 位運算bitset
//bitset存儲二進制數位。 //bitset就像一個bool類型的數組一樣,但是有空間優化——bitset中的一個元素一般只占1 bit,相當於一個char元素所占空間的八分之一。 //bitset中的每個元素都能單獨被訪問,例如對於一個叫做foo的bitset,表達式foo[3]訪問了它的第4個元素,就像數組一樣。 //bitset有一個特性:整數類型和布爾數組都能轉化成bitset。 //bitset的大小在編譯時就需要確定。如果你想要不確定長度的bitset,請使用(奇葩的)vector<bool>。 //bitset的相關函數 //對於一個叫做foo的bitset: foo.size() 返回大小(位數) foo.count() 返回1的個數 foo.any() 返回是否有1 foo.none() 返回是否沒有1 foo.set() 全都變成1 foo.set(p) 將第p + 1位變成1 foo.set(p, x) 將第p + 1位變成x foo.reset() 全都變成0 foo.reset(p) 將第p + 1位變成0 foo.flip() 全都取反 foo.flip(p) 將第p + 1位取反 foo.to_ulong() 返回它轉換為unsigned long的結果,如果超出范圍則報錯 foo.to_ullong() 返回它轉換為unsigned long long的結果,如果超出范圍則報錯 foo.to_string() 返回它轉換為string的結果 //定義一個bitset #include <iostream> // std::cout #include <string> // std::string #include <bitset> // std::bitset int main () { std::bitset<16> foo; std::bitset<16> bar (0xfa2); std::bitset<16> baz (std::string("0101111001")); std::cout << "foo: " << foo << '\n'; std::cout << "bar: " << bar << '\n'; std::cout << "baz: " << baz << '\n'; return 0; } /* foo: 0000000000000000 bar: 0000111110100010 baz: 0000000101111001 */ //bitset的運算 bitset的運算就像一個普通的整數一樣,可以進行與(&)、或(|)、異或(^)、左移(<<)、右移(>>)等操作。 #include <iostream> // std::cout #include <string> // std::string #include <bitset> // std::bitset int main () { std::bitset<4> foo (std::string("1001")); std::bitset<4> bar (std::string("0011")); std::cout << (foo^=bar) << '\n'; // 1010 (XOR,assign) std::cout << (foo&=bar) << '\n'; // 0010 (AND,assign) std::cout << (foo|=bar) << '\n'; // 0011 (OR,assign) return 0; }
16. sort函數
#include <iostream> #include <algorithm> using namespace std; int main() { //void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp); //第一個參數first:是要排序的數組的起始地址。 //第二個參數last:是結束的地址(最后一個數據的后一個數據的地址) //第三個參數comp是排序的方法:可以是從升序也可是降序。如果第三個參數不寫,則默認的排序方法是從小到大排序。 int arr[] = {9,2,4,6,3,4,8}; sort(a,a+7); for (int i=0;i<7;i++) cout << a[i] <<" "; return 0; }
17. sort自定義cmp函數
//對結構體排序 //方法一: #include <iostream> #include <vector> #include <algorithm> using namespace std; struct ss{ int a,b;//a是索引號,b是索引值 }; bool comp(const ss &a, const ss &b) { return a.a < b.a;//按索引排序號,通過改寫comp函數即可實現。 } int main() { vector<ss> v; s1.a = 4; s1.b = 41; s2.a = 1; s2.b = 12; s3.a = 5; s3.b = 52; v.push_back(s1); v.push_back(s2); v.push_back(s3); sort(v.begin(), v.end(), comp); for (int i=0; i<5; i++) cout << v[i].a << " " << v[i].b <<endl; return 0; } //方法二: struct ss { int a,b; bool operator < (const ss &s) const { return a < s.a; } }
18. cctype頭文件里的函數
//cctype 頭文件中的函數 isalnum(c)//當c是字母或數字時為真 isalpha(c)//當c是字母時為真 iscntrl(c)//控制字符為真 isdigit(c)//數字為真 isgraph(c)//當c不是空格但可打印時為真 islower(c)//小寫字母時為真 isupper(c)//大寫字母為真 isprint(c)//可打印字符時為真(即c是空格或c是具有可視形式) ispunct(c)//當c是標點符號時為真(即c不是控制字符、數字、字母、可打印空白中的一種) isspace(c)//當c是空白時為真(即c是空格、橫向制表符、總想制表符、回車符、換行符、進紙符的一種) isxdigit(c)//c是十六進制數字時為真 tolower(c)//如果c是大寫字母,輸出對應的小寫字母:否則原樣輸出c toupper(c)//如果c是小寫字母,輸出對應的大寫字母:否則原樣輸出c
19. C++11的解釋
//auto、decltype和新的函數語法編寫更好的代碼 //Lambda表達式 //區間迭代 //常量表達式 //右值引用和移動語義 //nullptr和強類型的枚舉
20. C++11好用的auto聲明
//編譯器可以從變量的初始化中得到它的類型 int x = 3; auto y = x; //使用模板特別是STL時auto很好用,如迭代器(iterator) map<string, string> address_book; address_book["Alex"] = "webmaster@towriting.com"; //遍歷需要一個迭代器,會這么做,map<string, string>::iterator iter = address_book.begin(); //而用auto,節省了時間而沒有丟掉表達式的意思。 auto iter = address_book.begin(); //區間迭代(range-based for loop) vector<int> vec; vec.push_back(10); vec.push_back(20); for (int &i: vec) { cout<<i; } //迭代map for (auto address_entry: address_book) { cout<<address_entry.first<<" "<address_entry.second<<endl; }
21. C++11特性中基於范圍的for循環
int arr[5] = { 1, 2, 3, 4, 5 }; for (auto num : arr) { cout << num << endl; } //范圍for循環修改數組,讓arr每個元素+1 #include <iostream> using namespace std; int main(){ int arr[5] = { 1,2,3,4,5}; for (int& num : arr)//如果是 (int num:arr)只是修改副本,原始數組數據不變 { num = num + 1; cout << num << endl; } cout << "———————————" << endl; for (int num : arr) { cout << num << endl; } system("pause"); return 0; }
22. C++特性中to_string
#include <iostream> #include <string> using namespace std; int main() { string s1 = to_string(123);//將123轉為字符串 string s2 = to_string(123.4);//將123.4轉為字符串 cout << s1 + s2 << endl;//將s1和s2字符串拼接后輸出 printf("%s\n", (s1+s2).c_str());//用printf輸出string,需要加一個.c_str() return 0; }
23. C++特性stoi,stod
//#include <string>
//stoi 、 stod 可以將字符串 string 轉化為對應的 int 型、 double 型變量 //非法輸入處理 stoi("123.4")//123.4不是整型變量,自動截取最前面的數字,直到遇到不是數字位置,所以遇到浮點型,會截取前面的整數部分;stoi(字符串,起始位置,2~32進制) stod("123.4abc")//會自動截取最前面的浮點數,直到遇到不滿足浮點數為止,如果最前面是小數點,會自動轉化后在簽名補0 //stof(string to float) //stold(string to long double) //stol(string to long) //stoll(string to long long) //stoul(string to unsigned long) //stoull(string to unsigned long long)
23.1 字符串轉數字
string s = "12345"; int x[s.length()]; for (int i=0;i<s.length();i++) x[i] = s[i] - '0'; // 減去字符0,也就是減去0的ASCII碼值48,數字字符減去'0'就得到了該數字。
23.2 字符串字母小寫變大寫
string s = "aBcDe"; for (int i=0;i<s.length();i++) if (s[i] >='a' && s[i] <= 'z') s[i] = s[i] -'a' + 'A'; //字母的ASCII碼值
23.3 數字轉字符串
string to_string(int val);
24. 如何在Dev_cpp中使用c++11的函數
//Dev-Cpp里面使用C++11特性的函數,比如刷算法中常用的stoi、to_string、unordered_map、unordered_set、auto這些,需要在設置里面讓dev支持c++11~ //在工具-編譯選項-編譯器-編譯時加入這個命令“-std=c++11” //tools->Compiler Options->General->Add the following commands when calling the compiler:-std=c++11
25.庫函數<math.h><cmath>
double pow(double, double);//x,y,返回x的y次方 double hypot(double, double);//a,b返回直角三角形第三斜邊的長度c double sqrt(double);//該函數返回參數的平方根。 int abs(int);//該函數返回整數的絕對值。 double fabs(double);//該函數返回任意一個浮點數的絕對值。
26. 進制轉換
//任意2-36進制數轉化為10進制數。 int atoi (string s, int radix) {//s是給定的radix進制字符串 int i, ans = 0; for (i=0; i<s.length(); i++) { char t = s[i]; if (t >= '0' && t <= '9') ans = ans*radix + t - '0'; else ans = ans*radix + t - 'a' + 10; } return ans; } //將10進制數轉換為任意的n進制數,結果為char型。 string intToA(int n, int radix) {//n為待轉數字,radix是指定的進制 string ans = ""; do { if (t>=0&&t<=9) ans += t + '0'; else ans += t - 10 + 'a'; n /= radix; }while (n!=0); reverse(ans.begin,ans.end()); return ans; }
//將n為radix進制 轉為 10進制 long long convert() {//long long類型防止轉化過程產生溢出 long long sum = 0; int index=0,temp=0; for (auto it = n.rbegin();it !=n.rend();it++){ temp = isdigit(*it) ? *it - '0' : *it - 'a' + 10; sum += temp * pow(radix, index++); } return sum; }
27. max_element()函數獲取最大值/位置
//查詢最大值所在第一個位置 //第一種添加比較方法,從頭到尾迭代 //第二種用自帶迭代器比較 #include <algorithm> #include <iostream> using namespace std; struct comp{ bool operator() (int i, int j) {//或 bool bools(int i, int j) {return i<j;} return i>j;//返回最小值 } } comp; int main () { int arr[] = {2,1,3,6,4,7}; cout << *max_element(arr,arr+6,comp) <<endl;//最小值,不帶*返回地址 cout << *max_element(arr,arr+6) << endl;//最大值 int i,pos; pos = *max_element(arr,arr+6);//獲取最大值 for (i=0; i< 7; i++){ if (arr[i] == pos) { break; } } printf("最大值位置 %d",i+1); return 0; }
參考:
【c++ bitset常用函數及運算符】https://www.cnblogs.com/RabbitHu/p/bitset.html