【初學者必備】c++快速入門經典詳細教學(零基礎小白也可以分分鐘學會)

2020-08-09 11:11:47

說明

本教學大部分參考柳婼的教學《從放棄C語言到使用C++刷演算法的簡明教學v4.7》

1.名稱空間using namespace std的解釋

這句話是使⽤「std」這個名稱空間(namespace)的意思~因爲有的時候不同⼚商定義的函數名稱彼此
之間可能會重複,爲了避免衝突,就給所有的函數都封裝在各⾃的名稱空間⾥⾯,使⽤這個函數的時
候就在main函數前⾯寫明⽤了什麼名稱空間,⼏乎在C++中使⽤到的⼀些⽅法如cin、cout都是在std
名稱空間⾥⾯的,所以可以看到using namespace std;這句話⼏乎成了我每段C++程式碼的標配,就和
return 0;⼀樣必須有~其實也可以不寫這句話,但是使⽤std⾥⾯的⽅法的時候就會麻煩點,要寫成這
樣:

#include<iostream>
int main ()
{
	int n;
	std::cin>>n;
	std::cout<<"hello ,xuyuanzhi"<<n+1<< std::endl;
	return 0;
}

2.cin和cout輸入輸出

就如同scanf和printf在stdio.h頭⽂件中⼀樣,cin和cout在頭⽂件iostream⾥⾯,看名字就知道,io
是輸⼊輸出input和output的⾸字⺟,stream是流,所以這個iostream頭⽂件⾥包含的⽅法就是管理⼀些輸⼊輸出流的~cin 和 cout ⽐較⽅便,不⽤像C語⾔⾥的scanf、printf那樣寫得那樣繁瑣, cin >> n; 和scanf("%d", &n); ⼀樣的意思,注意cin是向右的箭頭,表示將內容輸⼊到n中~同樣, cout << n;printf("%d", n); ⼀樣的意思,此時cout是向左的兩個箭頭,注意和cin區分開來~
⽽且不管n是double還是int或者是char型別,只⽤寫 cin >> n; 和 cout << n; 這樣簡單的語句就
好,不⽤像C語⾔中需要根據n的型別對應地寫%lf、%d、%c這樣麻煩~endl 和 「\n」 是⼀個意思,⼀般如果前⾯是個字串引號的話直接 「\n」 ⽐較⽅便。
例如:

cout << "hello, ⼩可愛~\n";
cout << n << endl;

cin和cout雖然使⽤起來更⽅便,但是輸⼊輸出的效率不如scanf和printf快,如果發現有題目超時了,可以換成scanf和printf再試一下

3.關於c++的標頭檔案

C++的頭⽂件⼀般是沒有像C語⾔的.h這樣的擴充套件後綴的,⼀般情況下C語⾔⾥⾯的頭⽂件去掉.h然後
在前⾯加個c就可以繼續在C++⽂件中使⽤c語⾔頭⽂件中的函數啦~⽐如:

#include <cmath> // 相當於C語⾔⾥⾯的#include <math.h>
#include <cstdio> // 相當於C語⾔⾥⾯的#include <stdio.h>
#include <cctype> // 相當於C語⾔⾥⾯的#include <ctype.h>
#include <cstring> // 相當於C語⾔⾥⾯的#include <string.h>

4.C++的變數宣告

C語⾔的變數宣告⼀般都在函數的開頭,但是C++在⾸次使⽤變數之前宣告即可~(當然也可以都放在函數的開頭),⽽且⼀般C語⾔⾥⾯會在for回圈的外⾯定義i變數,但是C++⾥⾯可以在for回圈內部定義~⽽且在for回圈⾥⾯定義的區域性變數,在回圈外⾯就失效啦(就是脫離這個區域性作⽤域就會查⽆此變數的意思),所以⼀個main函數⾥⾯可以定義好多次區域性變數i,再也不⽤擔⼼寫的回圈太多變數名i、j、k不夠⽤啦~

#include<iostream>
using namespace std;
int main(){
	int n;
	cin>>n;
	cout<<"hello,xuyuanzhi"<<n+1<<endl;
	int m;
	cin>>m;
	for(int i=0;i<n;i++){//這個i只在for回圈裏面有用,出了這個for回圈就相當於不見了
	  cout<<i;	   
		
	}
	cout<<endl;
	for(int i=0;i<m;i++){
		cout<<i+2;
	}
	return 0;
}

5.C++特有的bool變數

bool變數有兩個值,false和true,以前⽤C語⾔的時候都是⽤int的0和1表示false和true的,現在
C++⾥⾯引⼊了這個叫做bool(布爾)的變數,⽽且C++把所有⾮零值解釋爲true,零值解釋爲false
~所以直接賦值⼀個數字給bool變數也是可以的~它會⾃動根據int值是不是零來決定給bool變數賦值
true還是false~

bool flag = true;
bool flag2 = -2; // flag2爲true
bool flag3 = 0; // flag3爲false

6.C++特有的const定義常數

const int a = 99999999;

7.C++裡超好用的string類

以前⽤char[]的⽅式處理字串很繁瑣,現在有了string類,定義、拼接、輸出、處理都更加簡單啦~
不過string只能⽤cin和cout處理,⽆法⽤scanf和printf處理:

    string s="hello c++";//賦值字串
    string s1=s;
    string s2=s+s1; //字串拼接直接用+號就可以
    string s3;
    cin>>s3;//讀入字串 
    cout<<s<<endl<<s1<<endl<<s2<<endl<<s3<<endl;//輸出字串 

⽤cin讀⼊字串的時候,是以空格爲分隔符的,如果想要讀⼊⼀整⾏的字串,就需要⽤getline~
s的⻓度可以⽤s.length()獲取~(有⼏個字元就是⻓度多少,不存在char[]⾥⾯的什麼末尾的結束符之
類的~)

   string s;//定義一個空字串s 
   getline(cin,s);//讀取一行的字串,包括空格 
   cout<<s<<endl;
   cout<<s.length();//輸出字串s的長度 
   return 0;

string中還有個很常⽤的函數叫做substr,作⽤是擷取某個字串中的⼦串,⽤法有兩種形式:

string s2 = s.substr(4); // 表示從下標4開始⼀直到結束
string s3 = s.substr(5, 3); // 表示從下標5開始,3個字元

8.C++的結構體struct和C語言結構體的區別

定義好結構體stu之後,使⽤這個結構體型別的時候,C語⾔需要寫關鍵字struct,⽽C++⾥⾯可以省略
不寫:

struct stu {
 int grade;
 float score;
};
struct stu arr1[10]; // C語⾔⾥⾯需要寫struct
stu arr2[10];// C++⾥⾯不⽤寫

這個引⽤符號&要和C語⾔⾥⾯的取地址運算子&區分開來,他們沒有什麼關係,C++⾥⾯的引⽤是指
在變數名之前加⼀個&符號,⽐如在函數傳⼊的參數中int &a,那麼對這個引⽤變數a做的所有操作都
是直接對傳⼊的原變數進⾏的操作,並沒有像原來int a⼀樣只是拷⻉⼀個副本(傳值),舉兩個例
⼦:

void func(int &a) { // 傳⼊的是n的引⽤,相當於直接對n進⾏了操作,只不過在func函數
中換了個名字叫a
 a = 99;
}
int main() {
 int n = 0;
 func(n); // n由0變成了99
}
void func(int a) {// 傳⼊的是0這個值,並不會改變main函數中n的值
 a = 99;
}
int main() {
 int n = 0;
 func(n);// 並不會改變n的值,n還是0
}

9.C++STL之動態陣列vector的使用

之前C語⾔⾥⾯⽤int arr[]定義陣列,它的缺點是陣列的⻓度不能隨⼼所欲的改變,⽽C++⾥⾯有⼀個
能完全替代陣列的動態陣列vector,它能夠在運⾏階段設定陣列的⻓度、在末尾增加新的數據、在中
間插⼊新的值、⻓度任意被改變,很好⽤~它在頭⽂件vector⾥⾯,也在名稱空間std⾥⾯,所以使⽤
的時候要引⼊頭⽂件vector和using namespace std;
vector、stack、queue、map、set這些在C++中都叫做容器,這些容器的⼤⼩都可以⽤ .size() 獲
取到,就像string s的⻓度⽤ s.length() 獲取⼀樣~(string其實也可以⽤ s.size() ,不過對於
vector、stack、queue、map、set這樣的容器我們⼀般討論它的⼤⼩size,字串⼀般討論它的⻓度
length~其實string⾥⾯的size和length兩者是沒有區別、可以互換使⽤的。

#include<iostream>
#include<vector>
using namespace std;
int main(){
	vector<int> v1;//定義一個vector v1,定義的時候沒有分配大小 
	cout<<v1.size();//輸出vector v1的大小,此處應該爲0 
	return 0;
}

vector可以⼀開始不定義⼤⼩,之後⽤resize分配⼤⼩,也可以⼀開始就定義⼤⼩,之後還可以對它
插⼊刪除動態改變它的⼤⼩~⽽且不管在main函數⾥還是在全域性中定義,它都能夠直接將所有的值初
始化爲0(不⽤顯式地寫出來,預設就是所有的元素爲0),再也不⽤擔⼼C語⾔⾥⾯出現的那種int
arr[10];結果忘記初始化爲0導致的各種bug啦~

vector<int> v(10); // 直接定義⻓度爲10的int陣列,預設這10個元素值都爲0
// 或者
vector<int> v1;
v1.resize(8); //先定義⼀個vector變數v1,然後將⻓度resize爲8,預設這8個元素都是0
// 在定義的時候就可以對vector變數進⾏初始化
vector<int> v3(100, 9);// 把100⻓度的陣列中所有的值都初始化爲9
// 存取的時候像陣列⼀樣直接⽤[]下標存取即可~(也可以⽤迭代器存取,下⾯會講~)
v[1] = 2;
cout << v[0];

不管是vector、stack、queue、map還是set都有很多好⽤的⽅法,這些⽅法都可以在http://www.cplusplus.com/官⽅⽹站中直接查詢官⽅⽂檔,上⾯有⽅法的講解和程式碼範例~官⽅⽂檔是刷題時候必不可少的好夥伴~⽐如進⼊官⽹搜尋 vector ,就會出現vector擁有的所有⽅法,點進去⼀個⽅法就能看到這個⽅法的詳細解釋和程式碼範例~當然我們平時寫演算法⽤不到那麼多⽅法啦,只有⼏個是常⽤的~以下是⼀些常⽤的vector⽅法:

#include <iostream>
#include <vector>
using namespace std;
int main() {
	vector<int> a; // 定義的時候不指定vector的??
	cout << a.size() << endl; // 這個時候size是0
	for (int i = 0; i < 10; i++) {
		a.push_back(i); // 在vector a的末尾新增?個元素i
	}
	cout << a.size() << endl; // 此時會發現a的size變成了10
	vector<int> b(15); // 定義的時候指定vector的??,預設b??元素都是0
	cout << b.size() << endl;
	for (int i = 0; i < b.size(); i++) {
		b[i] = 15;
	}
	for (int i = 0; i < b.size(); i++) {
		cout << b[i] << " ";
	}
	cout << endl;
	vector<int> c(20, 2); // 定義的時候指定vector的??並把所有的元素賦?個指定的值
	for (int i = 0; i < c.size(); i++) {
		cout << c[i] << " ";
	}
	cout << endl;
	for (auto it = c.begin(); it != c.end(); it++) { // 使?迭代器的?式存取vector
		cout << *it << " ";
	}
	return 0;
}

容器vector、set、map這些遍歷的時候都是使⽤迭代器存取的,c.begin()是⼀個指針,指向容器的第
⼀個元素,c.end()指向容器的最後⼀個元素的後⼀個位置,所以迭代器指針it的for回圈判斷條件是it
!= c.end()
存取元素的值要對it指針取值,要在前⾯加星號~所以是cout << *it;
這⾥的auto相當於 vector::iterator 的簡寫,關於auto下⽂有講解~

10.C++STL之集合set的使用

set是集合,⼀個set⾥⾯的各元素是各不相同的,⽽且set會按照元素進⾏從⼩到⼤排序~以下是set的常⽤⽤法:

#include<iostream>
#include<set>
using namespace std;
int main(){
	set<int> s;//定義一個空集合s
	s.insert(1);//向集合裏面插入一個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中的值,如果結果等於s.end()表示未找到(因爲s.end()表示s的最後?個元素的下?個元素所在的位置)
	cout << (s.find(10) != s.end()) << endl; // s.find(10) != s.end()表示能找到10這個元素
	s.erase(1); // 刪除集合s中的1這個元素
    cout << (s.find(1) != s.end()) << endl; // 這時候元素1就應該找不到啦~
	return 0; 
}

11.C++STL之對映map的使用

map是鍵值對,⽐如⼀個⼈名對應⼀個學號,就可以定義⼀個字串string型別的⼈名爲「鍵」,學號int型別爲「值」,如 map<string, int> m; 當然鍵、值也可以是其它變數型別~map會⾃動將所有的鍵值對按照鍵從⼩到⼤排序,以下是map中常⽤的⽅法:

#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;
	return 0;
}

12.C++STL之stack的使用

棧stack在頭⽂件 #include 中,是數據結構⾥⾯棧~以下是常⽤⽤法:

#include <iostream>
#include <stack>
using namespace std;
int main() {
 stack<int> s; // 定義⼀個空棧s
 for (int i = 0; i < 6; i++) {
 s.push(i); // 將元素i壓⼊棧s中
 }
 cout << s.top() << endl; // 存取s的棧頂元素
 cout << s.size() << endl; // 輸出s的元素個數
 s.pop(); // 移除棧頂元素
 return 0;
}

13.C++STL之佇列queue的使用

佇列queue在頭⽂件 #include 中,是數據結構⾯的佇列~以下是常⽤⽤法:

#include <iostream>
#include <queue>
using namespace std;
int main() {
 queue<int> q; // 定義⼀個空佇列q
 for (int i = 0; i < 6; i++) {
 q.push(i); // 將i的值依次壓⼊佇列q中
 }
 cout << q.front() << " " << q.back() << endl; // 存取佇列的隊⾸元素和隊
尾元素
 cout << q.size() << endl; // 輸出佇列的元素個數
 q.pop(); // 移除佇列的隊⾸元素
 return 0;
}

14.C++STL之unordered_map和unordered_set的使用

unordered_map在頭⽂件 #include <unordered_map> 中,unordered_set在頭⽂件 #include<unordered_set> 中~
unordered_map和map(或者unordered_set和set)的區別是,map會按照鍵值對的鍵key進⾏排序
(set⾥⾯會按照集閤中的元素⼤⼩進⾏排序,從⼩到⼤順序),⽽unordered_map(或者
unordered_set)省去了這個排序的過程,如果偶爾刷題時候⽤map或者set超時了,可以考慮⽤
unordered_map(或者unordered_set)縮短程式碼運⾏時間、提⾼程式碼效率~⾄於⽤法和map、set
是⼀樣的~

15.C++的位運算bitset

bitset⽤來處理⼆進位制位⾮常⽅便。頭⽂件是 #include <bitset> ,bitset可能在PAT、藍橋OJ中不常⽤,但是在LeetCode OJ中經常⽤到~⽽且知道bitset能夠簡化⼀些操作,可能⼀些複雜的問題能夠直接⽤bitset就很輕易地解決~以下是⼀些常⽤⽤法:

#include <iostream>
#include <bitset>
using namespace std;
int main() {
 bitset<5> b("11"); //5表示5個⼆進位
 // 初始化⽅式:
 // bitset<5> b; 都爲0
 // bitset<5> b(u); u爲unsigned int,如果u = 1,則被初始化爲10000
 // bitset<5> b(s); s爲字串,如"1101" -> "10110"
 // bitset<5> b(s, pos, n); 從字串的s[pos]開始,n位⻓度
 for(int i = 0; i < 5; i++)
 cout << b[i];
 cout << endl << b.any(); //b中是否存在1的⼆進位制位
 cout << endl << b.none(); //b中不存在1嗎?
 cout << endl << b.count(); //b中1的⼆進位制位的個數
 cout << endl << b.size(); //b中⼆進位制位的個數
 cout << endl << b.test(2); //測試下標爲2處是否⼆進位制位爲1
 b.set(4); //把b的下標爲4處置1
 b.reset(); //所有位歸零
 b.reset(3); //b的下標3處歸零
 b.flip(); //b的所有⼆進位制位逐位取反
 unsigned long a = b.to_ulong(); //b轉換爲unsigned long型別
 return 0;
}

16.C++中的sort函數

sort函數在頭⽂件 #include <algorithm> ⾥⾯,主要是對個數組進⾏排序(int arr[]陣列或者vector陣列都⾏),vector是容器,要⽤v.begin()和v.end()表示頭尾;⽽int arr[]⽤arr表示陣列的⾸地址,arr+n表示尾部~

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
bool cmp(int a, int b) { // cmp函數返回的值是bool型別
 return a > b; // 從⼤到⼩排列
}
int main() {
 vector<int> v(10);
 for (int i = 0; i < 10; i++) {
 cin >> v[i];
 }
 sort(v.begin(), v.end());// 因爲這⾥沒有傳⼊參數cmp,所以按照預設,v從⼩到
⼤排列

 int arr[10];
 for (int i = 0; i < 10; i++) {
 cin >> arr[i];
 }
  sort(arr, arr + 10, cmp); // arr從⼤到⼩排列,因爲cmp函數排序規則設定了從⼤到⼩
 return 0;
}

注意:sort函數的cmp必須按照規定來寫,即必須只是 > 或者 <,⽐如:return a > b;或者return a < b;
⽽不能是 <= 或者 >= ,(實際上等於號加了也是毫⽆意義,sort是不穩定的排序),否則可能會出現
段錯誤~

17.C++中使用sort自定義cmp函數

sort預設是從⼩到⼤排列的,也可以指定第三個參數cmp函數,然後⾃⼰定義⼀個cmp函數指定排序規則~cmp最好⽤的還是在結構體中,尤其是很多排序的題⽬~⽐如⼀個學⽣結構體stu有學號和成績兩個變數,要求如果成績不同就按照成績從⼤到⼩排列,如果成績相同就按照學號從⼩到⼤排列,那麼就可以寫⼀個cmp陣列實現這個看上去有點複雜的排序過程:

#include <iostream>
using namespace std;
struct stu { // 定義⼀個結構體stu,number表示學號,score表示分數
 int number;
 int score;
}
bool cmp(stu a, stu b) { // cmp函數,返回值是bool,傳⼊的參數型別應該是結構體
stu型別
 if (a.score != b.score) // 如果學⽣分數不同,就按照分數從⼤到⼩排列
 return a.score > b.score;
 else // 如果學⽣分數相同,就按照學號從⼩到⼤排列
 return a.number < b.number;
}

bool cmp(stu a, stu b) {
 return a.score != b.score ? a.score > b.score : a.number <
b.number;
}

18.關於cctype標頭檔案裡的一些函數

剛剛在頭⽂件那⼀段中也提到,cctype本質上是C語⾔標準函數庫中的頭⽂件 #include<ctype.h> ,其實並不屬於C++新特性的範疇,在刷PAT⼀些字串邏輯題的時候也經常⽤到,但是很多⼈似乎不瞭解這個頭⽂件中的函數,所以在這⾥單獨提⼀下~可能平時我們判斷⼀個字元是否是字⺟,可能會寫:

char c;
cin >> c;
if (c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z') {
 cout << "c is alpha";
}

但是在cctype中已經定義好了判斷這些字元應該所屬的範圍,直接引⼊這個頭⽂件並且使⽤⾥⾯的函數判斷即可,⽆需⾃⼰⼿寫(⾃⼰⼿寫有時候可能寫錯或者漏寫~)

#include <iostream>
#include <cctype>
using namespace std;
int main() {
 char c;
 cin >> c;
 if (isalpha(c)) {
 cout << "c is alpha";
 }
 return 0;
}

常用方法:
isalpha 字⺟(包括⼤寫、⼩寫)
islower(⼩寫字⺟)
isupper(⼤寫字⺟)
isalnum(字⺟⼤寫⼩寫+數位)
isblank(space和\t)
isspace(space、\t、\r、\n)
cctype中除了上⾯所說的⽤來判斷某個字元是否是某種型別,還有兩個經常⽤到的函數:tolower和toupper,作⽤是將某個字元轉爲⼩寫或者⼤寫,這樣就不⽤像原來那樣⼿動判斷字元c是否是⼤寫,如果是⼤寫字元就 c = c + 32; 的⽅法將c轉爲⼩寫字元啦~這在字串處理的題⽬中也是經常⽤到:

char c = 'A';
char t = tolower(c); // 將c字元轉化爲⼩寫字元賦值給t,如果c本身就是⼩寫字元也沒有
關係~
cout << t; // 此處t爲'a'

19.關於C++11的解釋

C++11是2011年官⽅爲C++語⾔帶來的新語法新標準,C++11爲C++語⾔帶來了很多好⽤的新特性,⽐如auto、to_string()函數、stoi、stof、unordered_map、unordered_set之類的~現在⼤多數OJ都是⽀持C++11語法的,有些編譯器在使⽤的時候需要進⾏⼀些設定才能 纔能使⽤C++11中的語法,否則可能會導致編譯器上編譯不通過⽆法運⾏,⽐如我曾經寫過⼀篇部落格《如何在Dev-Cpp中使⽤C++11中的函數》(在本教學末尾)這個是針對DEV-cpp編譯器的,其他的編譯器如果發現不⽀持也可以百度搜尋⼀下讓編譯器⽀持C++11的⽅法~總之C++11的語法在OJ⾥⾯是可以使⽤的~⽽且很多語法很好⽤~以下講解⼀些C++11⾥⾯常⽤的新特性~

20.C++11裏面很好用的auto宣告

auto是C++11⾥⾯的新特性,可以讓編譯器根據初始值型別直接推斷變數的型別。⽐如這樣:

auto x = 100; // x是int變數
auto y = 1.5; // y是double變數

當然這個在演算法⾥⾯最主要的⽤處不是這個,⽽是在STL中使⽤迭代器的時候,auto可以代替⼀⼤⻓串的迭代器型別宣告:

// 本來set的迭代器遍歷要這樣寫:
for(set<int>::iterator it = s.begin(); it != s.end(); it++) {
 cout << *it << " ";
}
// 現在可以直接替換成這樣的寫法:
for(auto it = s.begin(); it != s.end(); it++) {
 cout << *it << " ";
}

21.C++11特性中的to_string

to_string的頭⽂件是 #include ,to_string最常⽤的就是把⼀個int型變數或者⼀個數字轉化爲string型別的變數,當然也可以轉double、float等型別的變數,這在很多PAT字串處理的題⽬中很有⽤處,以下是範例程式碼:

#include <iostream>
#include <string>
using namespace std;
int main() {
 string s1 = to_string(123); // 將123這個數位轉成字串
 cout << s1 << endl;
 string s2 = to_string(4.5); // 將4.5這個數位轉成字串
 cout << s2 << endl;
 cout << s1 + s2 << endl; // 將s1和s2兩個字串拼接起來並輸出
 printf("%s\n", (s1 + s2).c_str()); // 如果想⽤printf輸出string,得加⼀.c_str()
 return 0;
}

22.C++11特性中的stoi、stod

使⽤stoi、stod可以將字串string轉化爲對應的int型、double型變數,這在字串處理的很多問題中很有幫助~以下是範例程式碼和⾮法輸⼊的處理⽅法:

#include <iostream>
#include <string>
using namespace std;
int main() {
 string str = "123";
 int a = stoi(str);
 cout << a;
 str = "123.44";
 double b = stod(str);
 cout << b;
 return 0;
}

stoi如果遇到的是⾮法輸⼊(⽐如stoi(「123.4」),123.4不是⼀個int型變數):
1.會⾃動擷取最前⾯的數位,直到遇到不是數位爲⽌
(所以說如果是浮點型,會擷取前⾯的整數部分)
2.如果最前⾯不是數位,會運⾏時發⽣錯誤
stod如果是⾮法輸⼊:
1.會⾃動擷取最前⾯的浮點數,直到遇到不滿⾜浮點數爲⽌
2.如果最前⾯不是數位或者⼩數點,會運⾏時發⽣錯誤
3.如果最前⾯是⼩數點,會⾃動轉化後在前⾯補0
不僅有stoi、stod兩種,相應的還有:
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.如何在Dev-Cpp中使用C++11中的函數

如果想要在Dev-Cpp⾥⾯使⽤C++11特性的函數,⽐如刷演算法中常⽤的stoi、to_string、unordered_map、unordered_set、auto這些,需要在設定⾥⾯讓dev⽀持c++11~需要這樣做~在⼯具-編譯選項-編譯器-編譯時加⼊這個命令「-std=c++11」即可~