• 周四. 8月 11th, 2022

5G编程聚合网

5G时代下一个聚合的编程学习网

热门标签

C++语法总结

admin

11月 28, 2021

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 << '
';
  std::cout << "bar: " << bar << '
';
  std::cout << "baz: " << baz << '
';

  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) << '
';       // 1010 (XOR,assign)
  std::cout << (foo&=bar) << '
';       // 0010 (AND,assign)
  std::cout << (foo|=bar) << '
';       // 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"] = "[email protected]";
//遍历需要一个迭代器,会这么做,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
", (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

发表评论

您的电子邮箱地址不会被公开。