C++ primer 笔记

引用不是对象,指针是对象 

初始化空指针的方法:赋值为nullptr(推荐),null,0

字面值包括算术类型、指针、引用和某些类

d9a5b5000c904b54a92d7ec99261e35b.png

f440bd1e918341698e18b1cbd484fd06.png

类型别名:typedef double wages;//wages是double的同义词

c++11标准,使用using别名声明,using wages=double;

1ad97971ae694d0c92f08a12390e07a2.png

 #pragma once也可以防止同一个文件被include多次,但是可移植性差,有些编译器不支持。


string、vector、迭代器、数组

14085be4dafb4c099befb1803de650bd.png

(1)string字符串,cin读取遇到空白就停止,getline读取一整行遇到换行停止(允许有空格)
(2)string/vector.size()返回的不是int,是size_type类型,所以需要用decltype,例如:for(decltype (vector.size()) i=0;i<vector.size();i++)
(3)vector添加元素 puah_back()
(4)迭代器的类型为iterator和const_iterator 。常量只能用const_iterator,能读取不能修改所指的元素 如果只需读无须写最好用const_iterator
(5)c++11新标准中引入了cbegin和cend,不论是否是常量都返回const_iterator
(6)end指向尾元素的下一个位置,是一个不存在的元素位置,如果需要对迭代器赋空值或取空值,需要使用end()。

83bc39efb7b74b05bce4c99b0a874a93.png

(7)end-begin的结果是他们之间的距离也就是相差的元素数,加减整数就相当于移动了该距离

        下图是计算一组数字中首尾两数之和,从两端一直计算到中间的数字

78fcd21fb98e45e1890208fad235fb25.png

2be98fe37cb04417bf7de975d2a96dfa.png

 (8)在使用数组下标的时候,通常将其定义为size_t类型,这是一个无符号(unsigned)类型,定义在cstddef头文件中。例如:unsigned num;这样num才能和数组下标一起计算。

8c471a3323cb4d88a75727e5e20af217.png

 c6d33d2fc62c45e2b04070782e4b4558.png

 737b8ba2363242f68b4a0602ea7bd0be.png

 下题是一个除法程序,展示try,catch的简单用法:

int a, b;
	int num;
	try{
		cout << "请输入被除数和除数" << endl;
		cin >> a >> b;
		if (b == 0){
			throw runtime_error("除数不能为0");
		}
		num = a / b;
		cout << "结果是" << num;
	}
	catch(runtime_error err){
		cout << err.what()
		<< "请重新输入除数";
		cin >> b;
		num = a / b;
		cout << "结果是" << num;
	}
(9)有迭代器begin()和end()的类,可以使用范围for循环 

                        例:for(auto &value : array)

 函数

(1)如果函数不需要修改参数的值,最好把形参设为const
(2)函数列表初始化返回值
vector<string> process(){
    return{"abc","bcd"};
}

返回一个vector对象存放string

(3)如果返回值类型比较复杂,可以使用C++11中的尾置返回 

        例如:auto func(int i) ->int(*)[10];  表示返回指向一个含有10个整数的数组的指针

(4)允许main没有return语句,编译器会隐式地插入一条return 0                                             
(5)顶层const不算是一种新的形参,无法满足函数重载
(6)const_cast

27c143ab3c8a4594b59432a5c1e4116f.png

(7)默认实参,例如:

d338c0071e4745b48afc4b6cc2be09dd.png

e83270d2a7564531b94fe8647905d792.png 一旦某个形参有了默认值,则他后面的所有形参都必须有默认值

 (8)内联函数在返回值前加inline,适合规模较小频繁调用的函数
(9)constexpr

constexpr函数是能用于常量表达式的函数,必须有且只有一个return,不强制变量和返回值是常量表达式,但是不是的话就不可以用于常量表达式

a59d7070e97a4709820061c3e2a3a0d2.png

constexpr函数,被隐式地定义为内联函数

fc3ddd5aea3a42be80fd08078c7eb81d.png

c6fa0289cad948b386e2dd25cf45545a.png

d84e72e9850f4520b34160256c0b2b4c.png

cd2bddd8d8944e1e95c188d98cc2681d.png

(10)assert 

d4bc4aa4b9994ed88ddd8edd10916843.png

61f94aa86ac14876b02c8b0bf0c5272b.png 99edac0a32a44fdc856d56d31fd9d9f5.png

函数指针

f6a30caf6a184de1a0b9d81fb27e41c7.png

0ca953e7438a4463be86d691a02f498a.png

类 

(1)和数组类似,不能直接返回函数,但是可以返回指向函数的指针。
(2)成员函数的声明需要在函数内部,定义可以在内部也可以在外部。
(3)类的成员函数后面加const,表示这个函数不会修改这个类的数据成员,在常量成员函数中加mutable修饰的变量允许被修改,构造函数不能被声明为const。

        const对象只能调用const成员函数(const对象例如:const Student lisi(),lisi是一个const对象),const对象的数据不能被修改。

(4)struct和class的区别:class的成员默认是private,struct默认public

                                              class的继承默认是private,struct默认是public

                                              class可以用在模板参数中,struct不能

(5)IO类不能拷贝,只能引用
(6)this是一个const指针,只能用在成员函数,指向当前对象,所以可以用*this代表当前对象this 是一个指针,要用->来访问成员变量或成员函数。

构造函数初始化列表,负责为新创建的对象的数据成员赋初值,在冒号和花括号之间

344495ffdcab4e1780d72ee046eadd42.png

(7)友元补充 

8c0c6840377747b6adcbb2a933028629.png

37d2e3d5bbad4ca6a161b40ace988c6a.png

(8)如果成员是const、引用,未提供默认构造函数的类类型,必须通过构造函数初始化列表的方式提供初值,不能先初始化再赋值。
(9)委托构造函数

c7f80aedb0f5413394ca7f5a306763cb.png

(10)隐式的类类型转换 ,如果构造函数支持调用一个实参,那么就可以使用该实参隐式转换为类类型,只允许一步类类型转换,隐式类类型转换可能会破坏程序可读性。

a790ac2d4ce347e1a0aa15479f8dd19c.png

(11)explicit关键字声明构造函数可以阻止这种行为,这种函数只能直接初始化,不可以赋值的方式初始化

3943df881a554332bdc297ebe886bf58.png

(12)字面值类
3ed9cd1375474afa83cdee19786ee59e.png
(13)static静态成员声明在类内,定义在类外,所有对象能共享。static函数与类关联不与对象关联,所以不包含this指针,不能定于为const函数。
(14) 在类中初始化vector成员变量
vector<string> str(5);
vector<int> s(5,0);
//两种方式都会报错

//C++11之后正确的方式为:
vector<string> name = vector<string>(5);
vector<int> val{vector<int>(5,0)};

IO类

 (1)不能拷贝或者对流对象赋值,因此也不能将形参和返回值类型设置为流,需要用引用的形式,同时也不能设置为const。

c430de1202b744319c60861693bfdf1d.png

2c35eaabe49c4e7f91e205294100b047.png

(2)iostate的类型是位集合,对应流的当前状态。

b9911bf25fbd4c2f9cac6ed10229a354.png

(3)cin.ignore(a,ch)清除缓冲区中的数据,有两个参数数值型a,和字符型ch。常用来清除以回车结束的输入缓冲区的内容,消除上一次输入对下一次输入的影响,例如cin.ignore(100,'\n'),表示在读取100个字符或遇到回车后清除缓冲区。默认参数是cin.ignore(1,eof)把eof前的一个字符删掉。

(4)endl刷新缓冲区输出一个\n,ends刷新缓冲区输出一个空字符,flush刷新缓冲区不输出额外的字符。

(5)通过设置unitbuf可以控制是否需要缓冲区,cout<<unitbuf表示输出后立即刷新缓冲区。

(6)程序崩溃不会刷新缓冲区 

(7)每个流最多关联到一个流,但多个流可以同时关联到一个流。输入流被关联到输出流后,任何输入操作之前都会刷新缓冲区。cin和cout是默认关联的。

(8)tie函数有两个重载的版本,不带参数的返回指向输出流的指针(如果关联到一个输出流,就返回这个输出流的指针,如果没有关联,就返回空指针),第二个版本接受一个指向输出流的指针,将自己关联到此输出流。

(9)将字符串输入到缓冲区时会将结尾的换行一起输入进去。

cin从缓冲区读取数据,遇到空字符就结束读取,并写入空字符前的数据,但是空字符还存在于缓冲区中。cin.getline()默认遇到换行符作为读取结束的标志,并清除掉这个标志,也可以自己设置结束读取的标志,需要指定读取的字符的数量。

getline()是一个全局函数,用来处理string,在读取时遇到三种情况会停止:文件结束、遇到换行、输入达到上限。函数的定义为:

85d77d8456c94e08ab1468aa7ab994e9.png

delim是终结符,遇到该字符停止读取操作,不写的话默认为换行符。与cin.getline()相同,遇到终结符时会停止读取并且输入缓冲区中这个终结符也没有了。


顺序容器 

e0ebc07ba9db42bf90a0d34f5e9361b2.png

(1)顺序容器之间拷贝如果元素类型不同,不能直接拷贝,可以使用迭代器范围拷贝。


动态内存

allocator类

class Example
{
public:
    Example() : a(0) { cout << "example default constructor..." << endl; }
    Example(int x) : a(x) { cout << "example constructor..." << endl; }
    ~Example() { cout << "example destructor..." << endl; }
    int a;
};
int main()
{
    allocator<Example> alloc;
    Example *p = alloc.allocate(2);
    alloc.construct(p);
    alloc.construct(p + 1, 3);
    cout << p->a << endl;
    cout << (p + 1)->a << endl;
    alloc.destroy(p);
    alloc.destroy(p + 1);
    alloc.deallocate(p, 2);
}

输出如下:

example default constructor...
example constructor...
0
3
example destructor...
example destructor...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值