天天看点

C++回忆录

文章目录

    • 一、关于c++头文件
    • 二、关于语法
      • 1.用惯了python,记得每句后面加分号,且要添加类型定义
      • 2.循环
      • 3.输入输出
    • 三、关于string类型操作
    • 四、int类型与string类型的互换
      • 1.int—>string
      • 2.string—>int
    • 五、关于math头文件中的常用函数
    • 六、goto语句
    • 七、ASCII码转换
    • 八、进制转换
      • 1.指定格式输出
      • 2.使用字符串流string,stream
        • (1)8,16->10(string—>int)
        • (2)10->8,16(int—>string)
      • 3.itoa函数(int—>char)(除了2进制—>*进制)
      • 4.sprintf函数(int—>string)
      • 5.stoi函数(string—>int)(*进制—>十进制)
      • 6.bitset(int/char/string—>bitset)(十进制—>二进制)
    • 九、关于algorithm头文件中常用函数
      • 1.sort()函数
    • 十、类与结构体
      • 1.类
      • 2.结构体
    • 十一、向量
    • 十二、队列
      • 1.普通队列
      • 2.单调队列deque
      • 3.优先队列priority_queue(堆)
    • 十三、位运算符
    • 十四、C++中的字典——Map
      • 1.声明
      • 2.插入操作
        • 2.1单个[]插入
        • 2.2 insert函数
      • 3.取值
      • 4.容量查询
      • 5.迭代器
      • 6.删除交换
        • 6.1删除
        • 6.2交换
      • 7.顺序比较
      • 8.查找
      • 9.操作符
      • 10.遍历map
    • 十五、数组操作
      • 1.排序
      • 2.动态数组
        • 2.1一维数组
        • 2.2二维数组
    • 十六、栈
    • 十七、setw()函数
    • 十八、set

一、关于c++头文件

许久没有使用c++了,记录一下常用的固定公式。

#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<string>
#include<sstream>
#include<algorithm>
#include<vector>
#include<queue>
#include<math.h>
#include<bitset>
#include<map>
#include<stack>
#include<iomanip>
using namespace std;
int constant;//全局变量
int main(){}
           

二、关于语法

1.用惯了python,记得每句后面加分号,且要添加类型定义

2.循环

//for循环
for(int t=0;t<10;t++){}

//while
while(true){}

//do...while
do{}while(true)

//switch..case
switch(grade){
   case 'A' :
      cout << "很棒!" << endl; 
      break;
   case 'B' :
   case 'C' :
      cout << "做得好" << endl;
      break;
   case 'D' :
      cout << "您通过了" << endl;
      break;
   case 'F' :
      cout << "最好再试一下" << endl;
      break;
   default :
      cout << "无效的成绩" << endl;
}
           

3.输入输出

//输入
cin>>a>>b;

//输出
cout<<"123"<<endl;

//特定输入循环
//字符串(%s)、整数(%d)、字符(%c)、浮点数(%f)
while(scanf("%d.%d.%d...%d",&a,&b,&c,&d)!=EOF){}

//字符串输入,以空格/回车为结束
string a,b,c,d;
while(cin>>a){} //若输入"hello world",循环体执行两次
while(cin>>a>>b>>c>>d){} //输入"hello very happy world",循环体执行一次

//字符串输入,以行为单位
string tt;
getline(cin,tt);

           

三、关于string类型操作

//定义字符串
string ss="123456789";
string s1="555";
ss.append("ss");//在字符串后面追加“ss”->"123ss"
ss.append(&ss[0]);
ss.size();//返回int类型的字符串的长度
ss.empty();//判空
ss.substr(0,5);//获得字符串ss中从第0位开始的长度为5的字符串
ss.substr(6);//获得字符串ss中从第6位开始到结束的字符串
ss.find('2');//返回值是字母在母串中的位置(下标记录)(此处为1),如果没有找到,那么会返回一个特别的标记npos(此处为ss.npos)

ss.erase(10);// 从位置pos=10处开始删除,直到结尾
ss.erase(6, 4);//从位置pos=6处开始,删除4个字符
ss.erase(ss.begin()+10);//删除迭代器位置处的单个字符, 并返回下个元素的迭代器
ss.erase(ss.begin()+10, ss.end());//删除迭代器[first, last)区间的所有字符,返回一个指向被删除的最后一个元素的下一个字符的迭代器

/*下图描述*/
ss.begin();//函数返回一个迭代器,指向字符串的第一个元素
ss.end();//返回一个迭代器,指向字符串的末尾(最后一个字符的下一个位置)
ss.rbegin();//返回一个逆向迭代器,指向字符串的最后一个字符
ss.rend();//返回一个逆向迭代器,指向字符串的开头(第一个字符的前一个位置)

//连接两个字符串
cout<<ss+s1<<endl;
//倒转字符串
#include<algorithm>
reverse(ss.begin(),ss.end());
//如果出现“ error: too many arguments to function call, expected 1, have 2”的报错,则把“reverse”改为“::reverse”
           
C++回忆录

四、int类型与string类型的互换

1.int—>string

//int转换为string类型
int a=12;
string aa=to_string(a);

//或者,此法只能一个字符一个字符的转换,不能转换二位数以上的整数
int a=2;
char re=a+'0';
           

2.string—>int

//string类型转为int类型
string ss="123";
//stoi(字符串,起始位置,2~32进制),将n进制的字符串转化为十进制。
int s1=stoi(ss,0,10);//从ss字符串的0位置开始,以十进制转化

//或者
int s2=0;
for(int i=0;i<ss.size();i++){
	s2=s2*10+(ss[i]-'0');
}
           

五、关于math头文件中的常用函数

C++常用头文件——常用数学函数头文件

六、goto语句

goto label;
..
.
label: statement;
           

七、ASCII码转换

在计算机存储中,用ASCII码表示字符,如字符char a,b,及整形int m:

1.获取字符的ASCII码:(int)a 或 m = a;

2.获取ASCII码对应的字符:(char)a 或 a = m;

3.字符之间相加减,实质是对应的ASCII码相加减,结果为整形,如下列:

a - b 即a的ASCII码减去b的ASCII码,记为int k = a - b

结果:k

结果对应的字符:(char)k

转载:https://blog.csdn.net/jianyingyao7658/article/details/83443914?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-2&spm=1001.2101.3001.4242

C++回忆录

八、进制转换

1.指定格式输出

//c++
cout << "35的8进制:" << std::oct << 35<< endl;  
cout << "35的10进制" << std::dec << 35 << endl;  
cout << "35的16进制:" << std::hex << 35 << endl;  
cout << "35的2进制: " << bitset<8>(35) << endl;      //<8>:表示保留8位输出

//c
printf("%05o\n",35);    //按八进制格式输出,保留5位高位补零
printf("%03d\n",35);    //按十进制格式输出,保留3位高位补零
printf("%05x\n",35);    //按十六进制格式输出,保留5位高位补零
           

2.使用字符串流string,stream

#include<string>
#include<sstream>
           

(1)8,16->10(string—>int)

string s="20";
int a;
stringstream ss;
ss<<hex<<s;    //以16进制读入流中
ss>>a;        //10进制int型输出
           

(2)10->8,16(int—>string)

string s1,s2;
int a=30;
stringstream ss;
ss<<oct<<a;        //10进制转成八进制读入流中,再以字符串输出
ss>>s1;            
cout<<s1<<endl;        //输出:36
ss.clear();        //不清空可能会出错。
ss<<hex<<a;         //10进制转成十六进制读入流中,,再以字符串输出
ss>>s2;            
cout<<s2<<endl;        //输出:1e
           

3.itoa函数(int—>char)(除了2进制—>*进制)

#include <stdio.h>
#include <stdlib.h>
           
//函数原型
char *itoa(int value, char *str, int radix)

value 是被转换的整数
str 转换后存储的字符数组
radix 转换进制数,可以是 2, 8, 10, 16 等等
           

4.sprintf函数(int—>string)

当itoa不好使的时候,可以使用这个,功能更强大。

C++中sprintf()函数的使用详解

int your_number;
char itoa_str[60+1];
sprintf(itoa_str, "%d", your_number);
           

5.stoi函数(string—>int)(*进制—>十进制)

//函数原型
int stoi(const string &str, size_t* idx = 0, int base = 10)

str: 要转换的string
idx: 为size_t*类型,是从str中解析出一个整数后的下一个字符的位置
base: 指出string中要转换的数的进制,即str所代表的是个什么进制的数,如是base默认为10, 若base = 0, 表示由编译器自动判定str所代表的数的进制

//二进制——>十进制
int re=stoi("0001",0,2) //re=1
           

6.bitset(int/char/string—>bitset)(十进制—>二进制)

bitset<4> bitset1;  //无参构造,长度为4,默认每一位为0

bitset<8> bitset2(12);  //长度为8,二进制保存,前面用0补充

string s = "100101";
bitset<10> bitset3(s);  //长度为10,前面用0补充

char s2[] = "10101";
bitset<13> bitset4(s2);  //长度为13,前面用0补充

cout << bitset1 << endl;  //0000
cout << bitset2 << endl;  //00001100
cout << bitset3 << endl;  //0000100101
cout << bitset4 << endl;  //0000000010101
           

!!注意:取用bitset类型的index是反过来的!

例:bitset<8> re (“00011011”);

re[7] 为0

re[0] 为1

bitset<8> foo ("10011011");

cout << foo.count() << endl;  //5  (count函数用来求bitset中1的位数,foo中共有5个1
cout << foo.size() << endl;   //8  (size函数用来求bitset的大小,一共有8位

cout << foo.test(0) << endl;  //true  (test函数用来查下标处的元素是0还是1,并返回false或true,此处foo[0]为1,返回true
cout << foo.test(2) << endl;  //false  (同理,foo[2]为0,返回false

cout << foo.any() << endl;  //true  (any函数检查bitset中是否有1
cout << foo.none() << endl;  //false  (none函数检查bitset中是否没有1
cout << foo.all() << endl;  //false  (all函数检查bitset中是全部为1
           

九、关于algorithm头文件中常用函数

C++STL库之algorithm库

1.sort()函数

sort(first_pointer,first_pointer+n,cmp)

此函数有3个参数:

参数1:第一个参数是数组的首地址,一般写上数组名就可以,因为数组名是一个指针常量。

参数2:第二个参数相对较好理解,即首地址加上数组的长度n(代表尾地址的下一地址)。

参数3:默认可以不填,如果不填sort会默认按数组升序排序。也就是1,2,3,4排序。也可以自定义一个排序函数,改排序方式为降序什么的,也就是4,3,2,1这样。

//对数组A的0~n-1元素进行升序排序
sort(A,A+n);

//对向量V排序
sort(v.begin(),v.end());

//自定义排序
bool compare(int a,int b) return a<b; //升序排列,如果改为return a>b,则为降序
sort(v.begin(),v.end(),compare);
           

十、类与结构体

1.类

class Box
{
   public:
      double length;   // 长度
      double breadth;  // 宽度
      double height;   // 高度
      // 成员函数声明
      Box(){}//构造函数
      double get(void);
      void set( double len, double bre, double hei );
};
// 成员函数定义
double Box::get(void)
{
    return length * breadth * height;
}
 
void Box::set( double len, double bre, double hei)
{
    length = len;
    breadth = bre;
    height = hei;
}
int main( )
{
   Box Box1;        // 声明 Box1,类型为 Box
   Box Box2;        // 声明 Box2,类型为 Box
   Box Box3;        // 声明 Box3,类型为 Box
   double volume = 0.0;     // 用于存储体积
 
   // box 1 详述
   Box1.height = 5.0; 
   Box1.length = 6.0; 
   Box1.breadth = 7.0;
 
   // box 2 详述
   Box2.height = 10.0;
   Box2.length = 12.0;
   Box2.breadth = 13.0;
 
   // box 1 的体积
   volume = Box1.height * Box1.length * Box1.breadth;
   cout << "Box1 的体积:" << volume <<endl;
 
   // box 2 的体积
   volume = Box2.height * Box2.length * Box2.breadth;
   cout << "Box2 的体积:" << volume <<endl;
 
 
   // box 3 详述
   Box3.set(16.0, 8.0, 12.0); 
   volume = Box3.get(); 
   cout << "Box3 的体积:" << volume <<endl;
   return 0;
}
           

2.结构体

例:职工有职工号,姓名,年龄.输入n个职工的信息,找出3个年龄最小的职工打印出来。关键字顺序:年龄>工号>姓名,从小到大。

typedef struct Name{
    int age;
    int ID;
    string name;
}Name;

static bool comp(Name a,Name b)
{
    if(a.age<b.age)
        return true;
    else if(a.age==b.age)
    {
        if(a.ID<b.ID)
            return true;
        else if(a.ID==b.ID)
        {
            if(a.name<b.name)
                return true;
        }
    }
    return false;
}
 
int main()
{
    int N;
    while(cin>>N)
    {
        vector<Name> vec;
        Name temp;
        for(int i=0;i<N;i++)
        {
            cin>>temp.ID>>temp.name>>temp.age;
            vec.push_back(temp);
        }
         
        sort(vec.begin(),vec.end(),comp); //comp重写排序方式
         
        for(int i=0;i<3;i++)
        {
            cout<<vec[i].ID<<" "<<vec[i].name<<" "<<vec[i].age<<endl;
        }
    }
    return 0;
}
           

十一、向量

向量(Vector)是一个封装了动态大小数组的顺序容器(Sequence Container)。跟任意其它类型容器一样,它能够存放各种类型的对象。可以简单的认为,向量是一个能够存放任意类型的动态数组。

#include<algorithm>
#include<vector>
           

向量的例子可以看上面的结构体。

C++ vector 容器浅析

以下是常用使用方法:

//定义int类型的向量
vector<int> vec;

//在数组最后增加数据
vec.push_back(12);

//在数组最后移除数据
vec.pop_back();

//删除第i项
vec.erase(vec.begin()+i);

//清除数据
vec.clear();

//翻转数组,reverse属于头文件<algorithm>
reverse(vec.begin(),vec.end());
//翻转前m个
reverse(vec.begin(),vev.begin()+m);
//翻转后m个
reverse(vec.end()-m,vec.end());

//默认设置排序,从小到大,sort属于头文件<algorithm>
sort(vec.begin(),vec.end());

//自定义排序(本文章,第十章2.结构体,有相关应用)
//先写个规则函数
bool comp(int a,int b){
	return a > b; //return a<b升序排序;return a>b,则为降序 
}
//排序容器
sort(vec.begin(),vec.end(),comp)
//降序也可以将默认排序后的vec倒过来
reverse(vec.begin(),vec.end()); 

//若想要像数组一样取用,则如下定义
vector<int> vec = vector<int>(n, 0);//初始化n个0  

//注意,sort函数属于头文件<algorithm>,不仅可用于vector
int a[20]={2,4,1,23,5,76,0,43,24,65},i; 
for(i=0;i<20;i++) 
    cout<< a[i]<< endl; 
sort(a,a+20,compare);
           

十二、队列

1.普通队列

//定义int类型队列
queue<int> q;

//queue入队
q.push(x); //将x 接到队列的末端。

//queue出队
q.pop(); //弹出队列的第一个元素,注意,并不会返回被弹出元素的值。

//访问queue队首元素
q.front(); //即最早被压入队列的元素。

//访问queue队尾元素
q.back(); //即最后被压入队列的元素。

//判断queue队列空
q.empty();//当队列空时,返回true。

//访问队列中的元素个数
q.size();
           

2.单调队列deque

deque 则是一种双向开口的连续线性空间。所谓的双向开口,意思是可以在头尾两端分别做元素的插入和删除操作。

C++回忆录
//定义
deque<int> d;

d.size();//返回容器中元素的个数

d.empty();//判断容器是否为空

d.resize(num);//重新指定容器的长度为num,若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。

d.resize(num, elem); //重新指定容器的长度为num,若容器变长,则以elem值填充新位置,如果容器变短,则末尾超出容器长度的元素被删除。

//遍历容器
for(deque<int>::const_iterator it = d.begin(); it != d.end(); it++){
     cout<<*it<<" ";
}

d.push_back(elem);//在容器尾部添加一个数据

d.push_front(elem);//在容器头部插入一个数据

d.pop_back();//删除容器最后一个数据

d.pop_front();//删除容器第一个数据

d.at(idx);//返回索引idx所指的数据,如果idx越界,抛出out_of_range。

d.operator[];//返回索引idx所指的数据,如果idx越界,不抛出异常,直接出错。

d.front();//返回第一个数据。

d.back();//返回最后一个数据

d.insert(pos,elem);//在pos位置插入一个elem元素的拷贝,返回新数据的位置。

d.insert(pos,n,elem);//在pos位置插入n个elem数据,无返回值。

d.insert(pos,beg,end);//在pos位置插入[beg,end)区间的数据,无返回值。

d.clear();//移除容器的所有数据

d.erase(beg,end);//删除[beg,end)区间的数据,返回下一个数据的位置。

d.erase(pos);//删除pos位置的数据,返回下一个数据的位置。

           

3.优先队列priority_queue(堆)

/*声明形式:
type:数据类型;
container:实现优先队列的底层容器;
function:元素之间的比较方式;*/
priority_queue< type, container, function >
           

定义大顶堆和小顶堆:

//需要注意的是,如果使用less<int>和greater<int>,需要头文件:
#include <functional>

//大顶堆声明
//构造一个空的优先队列(此优先队列默认为大顶堆)
priority_queue<int> big_heap;   

//另一种构建大顶堆的方法
priority_queue<int,vector<int>,less<int> > big_heap2;

//小顶堆
//构造一个空的优先队列,此优先队列是一个小顶堆
priority_queue<int,vector<int>,greater<int> > small_heap;   
           

成员函数:

//假设type类型为int,则:
priority_queue<int> heap;   

heap.empty();//返回值为true,说明队列为空;
heap.size();//返回优先队列中元素的数量;
heap.pop();//删除队列顶部的元素,也即根节点
heap.top();//返回队列中的顶部元素,但不删除该元素;
heap.push(arg);//将元素arg插入到队列之中;

           

十三、位运算符

C++回忆录

十四、C++中的字典——Map

Map常见用法转载

1.声明

map<int, string> ID_Name;

// 使用{}赋值是从c++11开始的,因此编译器版本过低时会报错,如visual studio 2012
map<int, string> ID_Name = {
                { 2015, "Jim" },
                { 2016, "Tom" },
                { 2017, "Bob" } };
           

2.插入操作

2.1单个[]插入

map<int, string> ID_Name;

// 如果已经存在键值2015,则会作赋值修改操作,如果没有则插入
ID_Name[2015] = "Tom";
           

2.2 insert函数

// 插入单个键值对,并返回插入位置和成功标志,插入位置已经存在值时,插入失败
pair<iterator,bool> insert (const value_type& val);

//在指定位置插入,在不同位置插入效率是不一样的,因为涉及到重排
iterator insert (const_iterator position, const value_type& val);

// 插入多个
void insert (InputIterator first, InputIterator last);

//c++11开始支持,使用列表插入多个   
void insert (initializer_list<value_type> il);
           

示例:

#include <iostream>
#include <map>

int main()
{
    std::map<char, int> mymap;

    // 插入单个值
    mymap.insert(std::pair<char, int>('a', 100));
    mymap.insert(std::pair<char, int>('z', 200));

    //返回插入位置以及是否插入成功
    std::pair<std::map<char, int>::iterator, bool> ret;
    ret = mymap.insert(std::pair<char, int>('z', 500));
    if (ret.second == false) {
        std::cout << "element 'z' already existed";
        std::cout << " with a value of " << ret.first->second << '\n';
    }

    //指定位置插入
    std::map<char, int>::iterator it = mymap.begin();
    mymap.insert(it, std::pair<char, int>('b', 300));  //效率更高
    mymap.insert(it, std::pair<char, int>('c', 400));  //效率非最高

    //范围多值插入
    std::map<char, int> anothermap;
    anothermap.insert(mymap.begin(), mymap.find('c'));

    // 列表形式插入
    anothermap.insert({ { 'd', 100 }, {'e', 200} });

    return 0;
}
           

3.取值

Map中元素取值主要有at和[ ]两种操作,at会作下标检查,而[]不会。

map<int, string> ID_Name;

//ID_Name中没有关键字2016,使用[]取值会导致插入
//因此,下面语句不会报错,但打印结果为空
cout<<ID_Name[2016].c_str()<<endl;

//使用at会进行关键字检查,因此下面语句会报错
ID_Name.at(2016) = "Bob";
           

4.容量查询

// 查询map是否为空
bool empty();

// 查询map中键值对的数量
size_t size();

// 查询map所能包含的最大键值对数量,和系统和应用库有关。
// 此外,这并不意味着用户一定可以存这么多,很可能还没达到就已经开辟内存失败了
size_t max_size();

// 查询关键字为key的元素的个数,在map里结果非0即1
size_t count( const Key& key ) const; //
           

5.迭代器

共有八个获取迭代器的函数:* begin, end, rbegin,rend* 以及对应的 * cbegin, cend, crbegin,crend*。

二者的区别在于,后者一定返回 const_iterator,而前者则根据map的类型返回iterator 或者 const_iterator。const情况下,不允许对值进行修改。如下面代码所示:

map<int,int>::iterator it;
map<int,int> mmap;
const map<int,int> const_mmap;

it = mmap.begin(); //iterator
mmap.cbegin(); //const_iterator

const_mmap.begin(); //const_iterator
const_mmap.cbegin(); //const_iterator
           

返回的迭代器可以进行加减操作,此外,如果map为空,则 begin = end。

C++回忆录

6.删除交换

6.1删除

// 删除迭代器指向位置的键值对,并返回一个指向下一元素的迭代器
iterator erase( iterator pos )

// 删除一定范围内的元素,并返回一个指向下一元素的迭代器
iterator erase( const_iterator first, const_iterator last );

// 根据Key来进行删除, 返回删除的元素数量,在map里结果非0即1
size_t erase( const key_type& key );

// 清空map,清空后的size为0
void clear();
           

6.2交换

// 就是两个map的内容互换
void swap( map& other );
           

7.顺序比较

// 比较两个关键字在map中位置的先后
key_compare key_comp() const;

map<char,int> mymap;
map<char,int>::key_compare mycomp = mymap.key_comp();

mymap['a']=100;
mymap['b']=200;
mycomp('a', 'b');  // a排在b前面,因此返回结果为true
           

8.查找

// 关键字查询,找到则返回指向该关键字的迭代器,否则返回指向end的迭代器
// 根据map的类型,返回的迭代器为 iterator 或者 const_iterator
iterator find (const key_type& k);
const_iterator find (const key_type& k) const;

std::map<char,int> mymap;
std::map<char,int>::iterator it;

mymap['a']=50;
mymap['b']=100;
mymap['c']=150;
mymap['d']=200;

it = mymap.find('b');
if (it != mymap.end())
    mymap.erase (it); // b被成功删除
           

9.操作符

operator: == != < <= > >=

注意 对于==运算符, 只有键值对以及顺序完全相等才算成立。

10.遍历map

map<int, TaskInfo*> maps;
 
//以下循环是错误的.因为KEY不是顺序号
//for(int i=0; i<maps.size();  i++) 
//TaskInfo* pInfo = maps[ i ];
 
//正确遍历:
map<int, TaskInfo*>::iter iter;
for (iter=maps.begin(); iter!=maps.end(); iter++){
     GH_LOG_INFO("%d, %s", iter->first, iter->second);
}

           

十五、数组操作

1.排序

#include<algorithm>
int a[10]={1,2,3,4,5,6,7,8,9,10};
sort(a,a+alen); //alen是数组的长度
sort(a,a+2); //排序数组的前两项
           

2.动态数组

动态分配数组空间,对于溢出问题比较友好。

2.1一维数组

//一维
int *p=new int[20];

//释放空间
delete []p;  //释放这个一维的动态数组,而不是释放指针p。用完以后要记得释放掉
           

2.2二维数组

#include<iostream>
using namespace std;
int main()
{
   int m,n;   //输入数组大小
   int *column;
   int **p;   //声明一个二级指针
   cin>>m;
   column=new int[m];  //column用来记录每行元素的个数,因为每行元素的个数可能不同,如果都相同的话就不需要了
   p=new int*[m]; //创建了一个有m行的的二维动态数组;可以看成数组p[m]中每个元素都是指针,用来指向一个数组
   for(int i=0;i<m;i++)
   {
       cin>>n; 
       column[i]=n;
       p[i]=new int[n];  //确定每行元素的个数,p[i](一级指针)为每行元素的首地址

   }
   for(int i=0;i<m;i++) //输入每行元素的值
   {
       for(int j=0;j<column[i];j++)
         cin>>p[i][j];
   }
   cout<<"---------输出每行元素-----------\n";
   for(int i=0;i<m;i++)  //输出每行元素
   {
       for(int j=0;j<column[i];j++)
         cout<<p[i][j]<<" ";
       cout<<endl;
   }

   for(int i=0;i<m;i++)  //用完释放掉每行(释放二级指针)
       delete []p[i];
   delete []p;  //释放掉每行后,再释放这个二维数组(释放一级指针)
   cout<<"指针p的地址:"<<p;    //输出指针p的地址
   return 0;
}
           

十六、栈

//定义栈
stack<int> s1;

s1.empty(); //堆栈为空则返回真

s1.pop(); //移除栈顶元素,不返回元素

s1.push(); //在栈顶增加元素

s1.size(); //返回栈中元素数目

s1.top(); //返回栈顶元素
           

十七、setw()函数

C++ setw() 函数用于设置字段的宽度,语法格式如下:

setw(n)

n 表示宽度,用数字表示。

setw() 函数只对紧接着的输出产生作用。

当后面紧跟着的输出字段长度小于 n 的时候,在该字段前面用空格补齐,当输出字段长度大于 n 时,全部整体输出。

C++回忆录
#include <iostream>
#include <iomanip>

using namespace std;

int main()
{
    // 开头设置宽度为 4,后面的 runoob 字符长度大于 4,所以不起作用
    cout << setw(4) << "runoob" << endl;
    // 中间位置设置宽度为 4,后面的 runoob 字符长度大于 4,所以不起作用
    cout << "runoob" << setw(4) << "runoob" << endl;
    // 开头设置间距为 14,后面 runoob 字符数为6,前面补充 8 个空格 
    cout << setw(14) << "runoob" << endl;
    // 中间位置设置间距为 14 ,后面 runoob 字符数为6,前面补充 8 个空格 
    cout << "runoob" << setw(14) << "runoob" << endl;
    return 0;
}

/*
结果如下:
runoob
runoobrunoob
        runoob
runoob        runoob
*/
           
setw()函数内容转载自:https://www.runoob.com/w3cnote/cpp-func-setw.html

十八、set

set的特性是,所有元素都会根据元素的键值自动排序,set的元素不像map那样可以同时拥有实值(value)和键值(key),set元素的键值就是实值,实值就是键值。set不允许两个元素有相同的键值。

//定义
int arr[5] = {0,1,2,3,4};
set<int> iset(arr,arr+5);

set<int> ss;

ss.insert(5);//--在集合中插入元素
ss.begin();//--返回指向第一个元素的迭代器
ss.clear();//--清除所有元素
ss.count(5);//--返回某个值元素的个数,只会返回0和1
ss.empty();//--如果集合为空,返回true
ss.end();//--返回指向最后一个元素的迭代器
ss.equal_range(5);//--返回一对定位器,分别表示第一个大于或等于给定关键值的元素和第一个大于给定关键值的元素,这个返回值是一个pair类型,如果这一对定位器中哪个返回失败,就会等于end()的值。

/*
erase(iterator)  ,删除定位器iterator指向的值
erase(first,second),删除定位器first和second之间的值
erase(key_value),删除键值key_value的值
*/
ss.erase(5);//--删除集合中的元素

ss.find(5);//--返回一个指向被查找到元素的迭代器
ss.get_allocator();//--返回集合的分配器
ss.lower_bound(5);//--返回指向大于(或等于)某值的第一个元素的迭代器
ss.upper_bound(5);//--返回大于某个值元素的迭代器
ss.max_size();//--返回集合能容纳的元素的最大限值
ss.rbegin();//--返回指向集合中最后一个元素的反向迭代器
ss.rend();//--返回指向集合中第一个元素的反向迭代器
ss.size();//--集合中元素的数目

//交换集合s1和s2
s1.swap(s2);  //交换两集合