本教學大部分參考柳婼的教學《從放棄C語言到使用C++刷演算法的簡明教學v4.7》
這句話是使⽤「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;
}
就如同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再試一下
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>
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;
}
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
const int a = 99999999;
以前⽤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個字元
定義好結構體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
}
之前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下⽂有講解~
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;
}
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;
}
棧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;
}
佇列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;
}
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
是⼀樣的~
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;
}
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是不穩定的排序),否則可能會出現
段錯誤~
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;
}
剛剛在頭⽂件那⼀段中也提到,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'
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⾥⾯常⽤的新特性~
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 << " ";
}
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;
}
使⽤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)
如果想要在Dev-Cpp⾥⾯使⽤C++11特性的函數,⽐如刷演算法中常⽤的stoi、to_string、unordered_map、unordered_set、auto這些,需要在設定⾥⾯讓dev⽀持c++11~需要這樣做~在⼯具-編譯選項-編譯器-編譯時加⼊這個命令「-std=c++11」即可~