C++零碎笔记(3)

(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。两种关联容器pairmap
pair中有两个成员变量firstsecondfirst是键值,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提供的算法要包含头文件algorithmnumericalgorithm主要用于容器的操作,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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wrdoct

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值