(1)函数模板和模板函数。
template <class T>
T fun(T t){
//函数实现
}
函数模板是一个“框架”;模板函数是把函数模板中的类型参数实例化后生成的函数。
(2)#define
宏定义可以在预编译时期对代码进行替换,但它无法对类型进行检查。
(3)重载函数模板。
(4)定制类模板相当于实例化一个模板类。
(5)类模板中的每个实例都有自己的静态数据成员。
(6)结构体的默认访问权限是public
,类的默认访问权限为private
;
结构体无法使用类模板。
(7)数据类型别名:关键字typedef
,由用户为定义的数据类型名另外再取一个别名。
typedef flag int;
flag a;//flag可以作为int的数据类型来使用//int类型的别名就是flag
关键字typedef
具有作用域,范围是别名声明所在的区域(包括名称空间)。
typedef class asdfghj{
//成员列表
}myClass, ClassA;//这样令声明的类拥有myClass,ClassA两个别名
(8)枚举关键字enum
,代表了事物概念的分类。
enum 枚举名称{枚举1, 枚举2, ...枚举n,...};
枚举类型 变量名 = 枚举n;//枚举类型的名称作为数据类型来使用
可以用作switch
判断语句:
//枚举定义
enum Weekend {
MONDAY {
void desc() {
System.out.println("星期一");
}
},
TUESDAY {
void desc() {
System.out.println("星期二");
}
},
WEDNESDAY {
void desc() {
System.out.println("星期三");
}
},
THURSDAY {
void desc() {
System.out.println("星期四");
}
},
FRIDAY {
void desc() {
System.out.println("星期五");
}
},
SATURDAY {
void desc() {
System.out.println("星期六");
}
},
SUNDAY {
void desc() {
System.out.println("星期天");
}
};
}
//调用
void main() {
Weekend day = Weekend.SATURDAY;
switch (day) {
case MONDAY:
Weekend.MONDAY.desc();
break;
case TUESDAY:
Weekend.TUESDAY.desc();
break;
case WEDNESDAY:
Weekend.WEDNESDAY.desc();
break;
case THURSDAY:
Weekend.THURSDAY.desc();
break;
case FRIDAY:
Weekend.FRIDAY.desc();
break;
case SATURDAY:
Weekend.SATURDAY.desc();
break;
case SUNDAY:
Weekend.SUNDAY.desc();
break;
default:
System.out.println("非法星期");
break;
}
}
(9)关键字auto
是一个用来表示数据自动储存方式的关键字。
decltype
也是实现这一特性的关键字,它的作用是获取某一种数据类型。
int k1 = 3;
auto k2 = k1;//k2自动识别为int型
decltype(k1) p = 3;//p被初始化为k1的数据类型int
auto
声明的数据必须初始化;不能作为数组的类型声明;不可以在形参列表中使用。
(10)抛出异常使用throw
关键字。
try{
throw 1;//抛出异常//将整型值1作为异常信息抛出
}
catch(int error){
if(error == 1){ //异常信息
cout << "产生异常" <<endl;
}
}
在程序无法得到有关异常的信息而用省略号捕获任意异常:
catch(...){
cout << "未知异常!" << endl;
throw;
}
在对异常处理器进行排列时,应将派生类排在前面,将基类排在后面。
(11)标准异常类:
namespace std
{
//exception派生
class logic_error; //逻辑错误,在程序运行前可以检测出来
//logic_error派生
class domain_error; //违反了前置条件
class invalid_argument; //指出函数的一个无效参数
class length_error; //指出有一个超过类型size_t的最大可表现值长度的对象的企图
class out_of_range; //参数越界
class bad_cast; //在运行时类型识别中有一个无效的dynamic_cast表达式
class bad_typeid; //报告在表达试typeid(*p)中有一个空指针p
//exception派生
class runtime_error; //运行时错误,仅在程序运行中检测到
//runtime_error派生
class range_error; //违反后置条件
class overflow_error; //报告一个算术溢出
class bad_alloc; //存储分配错误
}
(12)宏定义#define
,#表示这是一条预处理命令,不分配内存空间,增加了代码的速度。有效范围为定义命令之后开始到此源文件结束;可以用#undef
终止宏定义的作用域。
#define PI 3.1415926 //在该程序中用PI替代3.1415926 //不加分号
#define MUL(x, y) ((x)*(y))
如果字符串长于一行,可以在该行末尾用一反斜杠“\”
续行。
(13)STL标准模板库从广义上分为: 容器(container) 算法(algorithm) 迭代器(iterator)。
头文件 | 内容 |
---|---|
queue | 容器适配器;队列queue <T> |
stack | 容器适配器;栈stack <T> |
vector | 容器;向量/数组vector <T> |
dqueue | 容器;双向队列dqueue <T> |
list | 容器;双向链表list <T> |
map | 容器;关联容器map<K,T> ;K表示关联对象T所在map中位置的信息 |
set | 容器;set <T> 表示的是一一对应的关系 |
(14)vector
容器,随机访问的数组类型。
//构造函数
vector<T> v; //采用模板实现类实现,默认构造函数
vector(v.begin(), v.end());//将v[begin(), end())区间中的元素拷贝给本身。
vector(n, elem);//构造函数将n个elem拷贝给本身。
vector(const vector &vec);//拷贝构造函数。
//常用赋值操作
assign(beg, end);//将[beg, end)区间中的数据拷贝赋值给本身。
assign(n, elem);//将n个elem拷贝赋值给本身。
vector& operator=(const vector &vec);//重载等号操作符
swap(vec);// 将vec与本身的元素互换。
//大小操作
size();//返回容器中元素的个数
empty();//判断容器是否为空
resize(int num);//重新指定容器的长度为num,若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
resize(int num, elem);//重新指定容器的长度为num,若容器变长,则以elem值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
capacity();//容器的容量
reserve(int len);//容器预留len个元素长度,预留位置不初始化,元素不可访问。
begin();//返回第一个元素的迭代器
end();//返回最后一个元素的迭代器
max_size();//最大容量
//数据存取操作
at(int idx); //返回索引idx所指的数据,如果idx越界,抛出out_of_range异常。
operator[];//返回索引idx所指的数据,越界时,运行直接报错
front();//返回容器中第一个数据元素
back();//返回容器中最后一个数据元素
//插入和删除操作
insert(const_iterator pos, int count,ele);//迭代器指向位置pos插入count个元素ele.
insert(const_iterator pos, ele);//迭代器指向位置pos插入元素ele.
push_back(ele); //尾部插入元素ele
pop_back();//删除最后一个元素
erase(const_iterator start, const_iterator end);//删除迭代器从start到end之间的元素
erase(const_iterator pos);//删除迭代器指向的元素
clear();//删除容器中所有元素
//反转
reverse();//颠倒元素的顺序
(15)list
容器,不支持随机访问(无法像数组一样通过索引来访问),插入元素的效率很高。
//构造函数
list<T> lstT;//list采用采用模板类实现,对象的默认构造形式:
list(beg,end);//构造函数将[beg, end)区间中的元素拷贝给本身。
list(n,elem);//构造函数将n个elem拷贝给本身。
list(const list &lst);//拷贝构造函数。
//赋值操作
assign(beg, end);//将[beg, end)区间中的数据拷贝赋值给本身。
assign(n, elem);//将n个elem拷贝赋值给本身。
list& operator=(const list &lst);//重载等号操作符
swap(lst);//将lst与本身的元素互换。
//元素插入和删除操作
push_back(elem);//在容器尾部加入一个元素
pop_back();//删除容器中最后一个元素
push_front(elem);//在容器开头插入一个元素
pop_front();//从容器开头移除第一个元素
insert(pos,elem);//在pos位置插elem元素的拷贝,返回新数据的位置。
insert(pos,n,elem);//在pos位置插入n个elem数据,无返回值。
insert(pos,beg,end);//在pos位置插入[beg,end)区间的数据,无返回值。
clear();//移除容器的所有数据
erase(beg,end);//删除[beg,end)区间的数据,返回下一个数据的位置。
erase(pos);//删除pos位置的数据,返回下一个数据的位置。
remove(elem);//删除容器中所有与elem值匹配的元素。
//大小操作
size();//返回容器中元素的个数
empty();//判断容器是否为空
resize(num);//重新指定容器的长度为num,若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
resize(num, elem);//重新指定容器的长度为num,若容器变长,则以elem值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
begin();//返回第一个元素的迭代器
end();//返回最后一个元素的迭代器
max_size();//最大容量
//数据的存取
front();//返回第一个元素。
back();//返回最后一个元素。
//反转排序
reverse();//反转链表,比如lst包含1,3,5元素,运行此方法后,lst就包含5,3,1元素。
sort(); //list排序
list
中的迭代器不支持“+”
号运算符,而指针与vector
中的迭代器都支持。
(16)关联容器也称为结合容器,是图结构的实现。其中K是key键值,通过键值可以迅速找到它的关联条目T。两种关联容器pair
和map
。
pair
中有两个成员变量first
和second
,first
是键值,second
是关联条目。map
是包含映射关系pair
的容器。
//构造函数
map<T1, T2> mapTT;//map默认构造函数:
map(const map &mp);//拷贝构造函数
//赋值操作
map& operator=(const map &mp);//重载等号操作符
swap(mp);//交换两个集合容器
//大小操作
size();//返回容器中元素的数目
empty();//判断容器是否为空
//插入数据元素操作
map.insert(...); //往容器插入元素,返回pair<iterator,bool>
map<int, string> mapStu;
mapStu.insert(pair<int, string>(3, "小张"));// 第一种 通过pair的方式插入对象
mapStu.inset(make_pair(-1, "校长"));// 第二种 通过pair的方式插入对象
mapStu.insert(map<int, string>::value_type(1, "小李"));// 第三种 通过value_type的方式插入对象
// 第四种 通过数组的方式插入值
mapStu[3] = "小刘";
mapStu[5] = "小王";
//删除操作
clear();//删除所有元素
erase(pos);//删除pos迭代器所指的元素,返回下一个元素的迭代器。
erase(beg,end);//删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
erase(keyElem);//删除容器中key为keyElem的对组。
//查找操作
find(key);//查找键key是否存在,若存在,返回该键的元素的迭代器;/若不存在,返回map.end();
count(keyElem);//返回容器中key为keyElem的对组个数。对map来说,要么是0,要么是1。对multimap来说,值可能大于1。
lower_bound(keyElem);//返回第一个key>=keyElem元素的迭代器。
upper_bound(keyElem);//返回第一个key>keyElem元素的迭代器。
equal_range(keyElem);//返回容器中key与keyElem相等的上下限的两个迭代器。
(17)更多的STL介绍见【C/C++】STL详解
(18)迭代器iterator
,模式定义如下:提供一种方法,使之能够依序寻访某个容器所含的各个元素,而又无需暴露该容器的内部表示方式。分为输入迭代器(只读)、输出迭代器(只写)、前向迭代器(读写,向前推进)、双向迭代器(读写,能向前和向后操作)、随机迭代器(读写,能以跳跃的方式访问容器的任意数据,是功能最强的迭代器)。
(19)使用STL提供的算法要包含头文件algorithm
和numeric
。algorithm
主要用于容器的操作,numeric
中的算法用来处理数组中的值。
for_each(first, last, func);//对first到last范围内的各个元素执行函数func定义的操作
fill(first, last,val);//把值val复制到迭代器first和last指明范围内的各个元素中
sort(first, last);//对迭代器first和last指明范围内的元素排序
transform(first, last,result,func);//将指定容器first到last范围中的元素执行func定义的操作,并将返回值依次应用到result迭代器所属的容器内 //将一个容器中的值搬运到另一个容器中
(20)lambda
表达式实质上是一个匿名函数。所在头文件为functional.h
。
[](){} 或者 []()->type{}
(21)I/O标准类中,进行标准I/O操作使用头文件iostream.h
;进行文件I/O操作使用头文件fstream.h
;进行串I/O操作使用头文件strstream.h
。
istream
是用于输入的流类,cin 就是该类的对象。
ostream
是用于输出的流类,cout 就是该类的对象。
iostream
是既能用于输入,又能用于输出的类。
ifstream
是用于从文件读取数据的类。
ofstream
是用于向文件写入数据的类。
fstream
是既能从文件读取数据,又能向文件写入数据的类。
istrstream
输入字符串类。
ostrstream
输出字符串类。
strstream
输入输出字符串流类。
(22)根基类ios:
(23)打开文件的两种方式:open
函数和构造函数。
//使用open函数
ifstream infile;//in是读 //声明一个输入流
infile.open("test.txt", ios::out);//第二个参数为打开方式,可多个一起用,中间用“|”连接
ofstream ofile;//out是写 //声明一个输出流
ofile.open("test.txt");
ofile << "name" << " ";//将字符name写入文件test.txt
fstream iofile;//声明一个输入/输出流
//构造函数
ofstream outfile("test.txt", ios::out);
(24)fstream
成员函数:
get(c);//从文件读取一个字符
getline(str,n,'\n');//从文件读取字符存入字符串str中,直到读取n-1个字符或遇到'\n'时结束 //按行读取
peek();//查找下一个字符,但不从文件中取出 //一般使用peek()查看是否已经到达文件结尾
put(c);//将一个字符写入文件
putback(c);//对输入流放回一个字符,但不保存
eof();//如果读取超过eof,返回True //eof()返回值没到结尾返回0
ignore(n);//跳过n个字符,参数为空时,表示跳过下一个字符
//举例
while(!ifile.eof()){ //文件没读取到结尾 执行while循环
......
}
while (infile.peek() != EOF){//文件没读取到结尾 执行while循环
......
}
while(infile.get(c)){//能读到一个字符
outfile << c; //写入一个字符
}
//检查
fstream file("test.txt");
if(file.fail()){
cout << file.rdstate <<endl; //通过rdstate方法获得文件状态
}
(25)对二进制数据读取要用read
方法,写入二进制数据要用write
方法。
(26)文件指针:
seekg //位移字节数,可以设置文件读指针的位置
seekp //位移字节数,可以设置文件写指针的位置
tellg //能够查找返回文件读指针的位置
tellp //能够查找返回文件写指针的位置
ios::beg //文件头部
ios::end //文件尾部
ios::cur //文件指针的当前位置
//举例
seekg(0, ios::beg);//将文件指针移动到相对于文件头部0个偏移量的位置,即指针在文件头
ioFile.seekg(0, ios::end); //定位读指针到文件尾部 //tellg 可以获取文件长度
(27)程序通过remove
函数将用户输入的文件删除。所在头文件为#include<cstdio>
。
remove(fileName); //删除成功返回0
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~