P4
public放函数,praviate放数据,需要用的时候在public写函数取就行了。特殊情况也可以直接在praviate直接写个friend函数。
const 可以给变量,也可以给函数。const不是绝对的常量,只是编译器的手脚,它让编译器在编译的时候不能修改,程序结束以后可以手动改的,所以说它不是绝对的常量。
const最重要就是,凡是不变的都要注意加上const,如果有一个没加,其它的却加了,就会冲突报错。
尽量用传引用,但是传引用还和指针不一样。a+=b a的值变了,b没变 所以a只能传值,,b还是传引用。 const 和$ 引用 都是和int一样,而且很多时候都是定义函数的时候用, 是形参,,不是实际运算的。
初始化的写法
批量移动
以批量移动目录(dev)下所有指定文件到另一个文件夹(dev/shell/)为例:
find dev -name “*.wav” | xargs -i mv {} dev/sh
vector v vector内部是一个类,it肯定是指针, it就是类,所以it.name it->name
vector<person *> v vector内部是一个地址, it就是一个地址, it是一个指针,,所以!!it就是括号内的类型, 上面it就能直接.name了, 这里it还要指针, *it->name。所以it是一个指向指针的指针。
string append 追加
find rfind 返回下标位置 rfind就是right 从右往左, 找到返回第一个位置,找不到返回-1
replace (1,3,1111) 原来是abcdefg 现在把bcd 3个 替换为1111
compare 字符串ascii码比较主要是比是否相等,相等返回0 大于返回1 小于返回-1,,英文还能比,中文更没意义,所以是看是否相等,相等返回0
hello str.at(索引位置) 就能访问单个字符 甚至能直接修改单个字符
inset 从哪个位置起,插入谁
erase从哪个位置起 删几个
substr !!c++ 总是 从哪个位置,取几个,不会写 从哪个位置到哪个位置。但迭代器的话就是区间
vector 的下标,插入, 删除都要用迭代器,不存在用下标。v1.begin()就是迭代器,
swap 用一个匿名对象,执行完后编译器自动回收, 把浪费的空间指针交换到它身上,编译器自己回收,就收缩内存了。
10万个数的vector需要扩展30次,v.reserve(10万)直接预留。
dequee 能头插,所以访问就比vector慢。
deque 内部 insert deque(d1.begin(),d2,begin(),d2.end())
erase 要用迭代器, 一般都是begin()或end,如果要删中间的,那么先创建一个迭代器,让他++ 然后再用它来删。
deque除了迭代器 []和at也能访问,,排序用迭代器。
栈和队列,中间的元素都不能访问,只有队头和队尾。
双向循环列表list 都不是最基本, 比起数组 vector,list插入和删除中间元素很快,但是遍历也不快,vector插入删除就不快,list比vector复杂,占空间大,,list也不浪费,vector会浪费
vector是在一个连续的内存,,除非不够用了,它一直都在那个内存那里,,但list会一直跳,灵活
vector 优点就是它是连续内存,能快速用[] 随机访问,而不用迭代器,但也因此增删很笨,只能在尾部的时候快,而且还会容量不够,重新复制到一块新的内存,浪费空间。
list 和vector不一样,是用指针的所以不能用[],也不能用at。,不支持跳跃,所以不用+号,往前走不用+1 就直接++就得了,也能–
支持迭代器的容器和不支持迭代器的容器,用的是两套算法, 迭代器的用的是标准库的,,不支持迭代器的只能用特定容器内部的算法。
list的排序,对人的排序,自己定义,指定规则用的是仿函数,例如身高>身高 return true。
set 和multtset就一个区别,能不能放重复元素
set的删除 怎么用,它会自动排序,那么删哪个呢? find 就很有用了,速度肯定比较快,set的count都是0或1 和find一样, multiset的count就有用了,find返回迭代器
仿函数就是重载() 小括号, 本来是大到小排序, 重载以后就是小到大,
binary search 二分查找 只返回 true or false
函数内引用是局部的,所以要加一个static 静态变量,这样的话,函数结束,这个变量还在。这个别名还能用
引用本质是指针常量,所以引用初始化以后不能换别的所指。编译器帮忙做了很多指针的解引用
还有常量引用!
函数默认参数,如果某个位置有了默认参数,那么这之后的位置都得有默认参数。
函数声明和实现,只能一个有默认参数
深拷贝: 自己实现拷贝构造
a = new int(*a),,自己new一块内存, new的值就是原来的内存的值,所以直接解引用
当类的属性和形参重名时,就可以用this来说明是一个这个类的对象的属性,而不是形参。
一个类,有函数,有属性,函数内部 this 就是这个类, this指针,指的就是谁调用这个类,就是那个对象,那个对象他有属性,我用this指这个属性,,它就和形参区分开了。
void ()
{
} 没有返回了,我加一个*this就返回自己 前面类型也改为相应的类型,链式编程,用值返回会返回新的对象, 引用因为有const就能保证是同一个套娃
调用属性的时候,其实默认是有一个this指针的。 所以一单指针本来就是null空的,所以属性也不存在
auto_ptr 不允许隐式构造, auto_ptr a_p1 = p 不行 ,p必须自带类型,不能让编译器来推
auto_ptr 不能将同一个裸指针 赋值给多个 auto_ptr,因为析构的时候把他删了,就不能再次析构了
auto_ptr 不能拷贝构造,因为拷贝构造,成就别人,它自己又被删了
double是64双精度,8个字节,64个Bit,1bit表示符号,11bit 表示指数,52bit 表示小数。取值范围10的308次,精度15位有效数字
FP32 是单精度浮点数,4个字节,32个bit,1bit表示符号,8bit 表示指数,23bit 表示小数。2^23是8 388 608。取值范围是2的128次,即10的38次。 8.3E7,精度7位有效数字,
FP16 半精度浮点数,2个字节,16个bit,1bit表示符号,5bit 表示指数,10bit 表示小数。
2的5次是32,取一半是16。2的16次是65 536,即取值范围是6万,精度2的10次是1024,4位有效数字
int8 8个bit,1表示符号,7个数字,表示整数,2的7次是128。一共256个数
引用是指针常量,指向不能改,引用谁就是谁。
数组指针,因为[]的优先级比*高,所以要int (*p)[],所以需要这个括号。
例如p[3][4]是三行4列,那么一行的地址是4个int。
二维数组!的名称是一个数组指针!所以 ((p+1)+2) 相当于p[1][2], p是它的行的一个指针,p的步长就是列的地址偏移,p+1就是第1行就是4个int,再加2就是第二列了。
二维数组名通常都是一维数组指针,所以*(*(p+1)+2),特殊情况sizeof是整个二维数组步长, &arr,取地址的时候是二维数组指针,不是一维了。
一维数组名通常是指向首地址的指针,特殊情况sizeof是整个步长,&arr取地址时是一维数组指针。步长也是一下跳整个.
值传递,是拷贝了一份,不会影响实参,效率低。
指针传递,直接通过指针操作原来数据,影响实参,效率高。本质是值传递,传的是一个地址。指针实在的是一个地址。引用创建了一个const 指针来存变量,用的时候给它起了别名,你直接用它就行,因为他就是一个指向原来变量还加了*取值符号,确实是别名。它的那个名字已经是那块内存的数据,不是地址。
引用是常量指针,不能变,必须初始化,影响实参,效率高。可以加const就不影响了。
指针弱于引用的是,传指针本质是传值,所以在函数中改这个地址指的东西可以,但是改这个地址本身是没用的,但改引用呢?