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