指针数组
数组指针
char *p[10] 是指针数组,数组里存放了10个指针---------------本质数组
char (*p1)[10] 是数组指针,p1是一个指向存放10个char类型的数组的指针---------------本质指针
typedef void (*FUN)();定义FUN为一个函数指针,指向一个函数,该函数返回值为void,参 数为空,调用有fun()和(*fun)()-----取函数入口地址
*******************************************
必须初始化
列表
构造函数初始化时必须采用初始化列表一共有三种情况,
1.需要初始化的数据成员是对象(继承时调用基类构造函数)
2.需要初始化const修饰的类成员
3.需要初始化引用成员数据
附:初始化列表按类中声明变量的先后顺序来初始化,与初始化列表的顺序无关
static 变量在类内部声明,但是必须在类的外部进行定义和初始化
static 常量成员在类内、外初始化都可以
const 常量在类内部声明,但是定义只能在构造函数的初始化列表进行
*********************************************
模板类
模板类:
(1)可用来创建动态增长和减小的数据结构
(2)它是类型无关的,因此具有很高的可复用性。
(3)它在编译时而不是运行时检查数据类型,保证了类型安全
(4)它是平台无关的,可移植性
(5)可用于基本数据类型
说明:
template <typename T1, typename T2>
template <class T1, class T2>
函数模板:
(1)函数模板的实例化由编译器实现
(2)类模板的成员函数都是函数模板
(3)没使用过的成员函数(即函数模板)不会被实例化
**********************************************************
静态局部变量
的作用域
静态局部变量的作用域与一般局部变量一样,
二者区别在于以上两点:
一般局部变量在函数调用结束后释放变量占用的存储单元,
而静态局部变量不释放静态变量在内存的静态存储区,静态数据一直占有着该存储区单元直到 程序结束;
****************************************************************
sizeof()
引用: 所指向的变量(对象)的大小
函数: 函数返回值类型的大小,函数并不会被调用
虚函数: 指针相同
指针变量: 32位为4个字节,64位为8个字节
*指针: 指针的类型所对应的大小
数组: 数组所占用的内存字节数;数组为函数参数,蜕变成指针
结构体: 成员所占字节+内存对齐
联合体: 占内存最大的成员所占字节
继承: 派生类的sizeof结果需要加上基类的sizeof结果
当基类和派生类均有虚函数时,只计算一次sizeof(虚表指针)
string: 为类类型,大小为28
、、、、、、、、、、、、
类: (1)空类的大小为1字节,为了区分两个空类
(2)类中的函数不占空间,除非是虚函数(有几个父类就有几个虚函数表指 针)
(3)静态数据成员放在全局数据成员中,它不占类实例大小
*****************************************************************************************
内存对齐:
(1)起始位置要从该成员大小或者成员的子成员大小的整数倍开始
(2)结果,.必须是其内部最大成员的整数倍.不足的要补齐
(3)最大元素大小的整数倍地址开始存储
附:有#pragma pack(n) 表示设置为n字节对齐
每一个数据成员的偏移量必须是min(#pragma pack()指定的数,这个数据成员的自身 长度) 的倍数
*******************************************************************************
大端模式
与小端模式:
大端:低字节放在高地址
小端:低字节放在低地址
按字节进行放,16进制两位数代表一个字节
********************************************************************************
宏替换:
纯文本替换
预处理指令都是以#号开头的
宏替换在编译前进行,不分配内存
一行上只能出现一个有效的预处理命令行
可以把define定义成标识符
头文件#include后面加<>和""的区别
后面加<>时,是查找系统的标准库函数,通过系统环境变量指定系统的库目录;
后面加""时,是在用户的工作目录下查找,用户的工作目录由编译器选项指定;
使用const比使用define有一下几种好处:
(1)const会进行数据类型检查,而define不会
(2)const效率高,因为const定义的常量,没有在内存中存储,而是在符号表中,每次访问这 个数据的时候,少了从内存中读取和存储过程,效率高。
因此尽量还是使用const常量
***********************************************************************
运算符优先级:
单目与强转,乘除模加减
位移比大小,等价与异或---------按位与、异或、或
逻辑是与或,三目后赋值
逗号是最小,返回右边值
***************************************************************************
类
Qiniuome a();是函数声明.
Qiniuome a;才是调用无参的构造函数
****************************************************************************
进制表示:
十进制整形常量:由0~9的一连串数字构成,第一个数字即最高位不能为0
八进制整形常量:以0开头,后面紧跟的数字由0~7构成。-023表示八进制的整形常量-23
十六进制整形常量 :以0x或0X开头。-0x46表示十六进制的整形常量-46
实数的小数点前后的数字都可以不写
科学表示法规定格式为:“实数e整数”或“实数E整数,幂是整数,不能写成实数
***********************************************************************************
结构体
定义的方式:
1,先构造,后定义 struct stu{ int num; char name[20];};struct stu s1;
2,构造同时定义 struct stu{ int num; char name[20]; }s,s1;
3,构造同时定义,省略类型名,但不能定义新变量struct { int num; char name[20]; }s,s1;
4,定义一个结构体类型用typedef: typedef struct Student{int a;}Stu; Stu stu1;
4中student可写可不写
附:
c中结构体不能有函数,只是变量的聚合体,必须写struct
C++中可以有函数,可以省略struct
***************************************************************************
x++只能作为右值,而++x既可作为左值又可作为右值
******************************************************************************
转义字符:
a响铃 退格符 tab
************************************************************************
文件操作函数:
fclose:函数返回值为0;否则,返回值为非0
seekg()设置输入、输出流的位置
tellg()返回输入、输出流的位置
***************************************************************************
常量指针
指针常量:
int *const pt *在const后指针指向不可变,值可变
int const *pt或const int *pt const在*后值不可变,指针指向可变
*要在数据类型之后
*********************************************************************************
数组++:
int a[5] a+1代表a[1] &a+1: 代表&a相当于是二维指针。 &a+1 就是从a向后跳过 一个完整的数组所占用的内存空间
附:数组名可以直接给指针赋值,但基本数据类型不行,返回的是值,不是地址
*********************************************************************************
c和c++本身没有输入和输出语句,但是有控制输入和输出的流操作符<<和>>
**********************************************************************************
fork:
在原进程数乘以二,复制原进程缓冲区中内容,
printf("-")会在缓冲区中,printf("-
")会被输出,没在缓冲区中
***************************************************************************************
线程同步
和通信:
方式: 事件、临界区、互斥量、信号量可以实现线程同步
通信: 管道、有名管道、信号量、信号、共享内存、消息队列、套接字
***************************************************************************
运算符重载:
C++规定=,[ ],(),->这四个运算符只能被重载为类的非静态成员函数,其他的可以被友元重 载,主要是因为其他的运算符重载函数都会根据参数类型或数目进行精确
匹配,这四个不具有 这种检查的功能,用友元定义就会出错
****************************************************************************
NULL与nullptr区别:
c++11后为了明确区分null与0,引入特指空指针nullptr
****************************************************************************
大小写字母和数字的ascii码值:
0-9:48-57
A-Z:65-90
a-z:97-122
********************************************************************
c++内存模型:
(1)堆:动态申请的内存
(2)栈:局部变量
(3)全局/静态存储区(.bss段和.data段) :全局和静态变量被分配到同一块内存中。在C语 言中,未初始化的放在.bss段中,初始化的放在.data段,在C++里则不区分了
(4)常量存储区 (.rodata段) :存放常量,不允许修改
(5)代码区 (.text段) :存放代码(如函数)
附:
栈:在Windows下,向低地址扩展,是一块连续的内存的区域,大小为2M
堆:向高地址扩展,是不连续的内存区域,是由于系统是用链表来存储,所以大量的 new/delete 操作会造成内存空间的不连续
**************************************************************************
delete:
当用delete来释放用new int[]申请的内存空间时,由于其为基本数据类型没有析构函数,所以 使用delete与delete []相同,两者都会释放申请的内存空间,若是自定义的数 据 类型,有析构 函数时,用new []申请的空间,必须要用delete []来释放,因为要delete []时会逐一调用对象 数组的析构函数,然后释放空间
*******************************************************************************
统计1,0个数:
统计0:
while((x+1))
{
n++;
x=x|(x+1);
}
统计1:
while(x)
{
count++;
x=x&(x-1);
}
*******************************************************************************
try-catch
throw:
try:可能发生异常的语句
catch:捕获,并处理异常(printStackTrace()用来跟踪异常事件发生时执行堆栈的内容)
throw:方法内部抛异常
throws:声明方法异常
finaly:代码中无论是否有异常都会执行,清除资源
****************************************************************************
指针赋值:
除了数组外,给指针赋值需要用&,string也要用&
指针运算:
指针支持+、-、+=、-=、++、--
两个可加减即地址加减
***************************************************************************
纯虚函数:
(1)纯虚函数可以有函数体!!!函数体必须定义在类的外部!!!(C++ Primer)
(2)有纯虚函数的类叫抽象类,它不能用来定义对象
(3)抽象类的派生类如果不实现纯虚函数,它也是抽象类
多继承:
产生二义性:使用成员名限定法消除。如 c1.A::f();
虚继承:
(1)声明虚基类只需要在继承方式前面加上 virtual 关键字
(2)在最后的派生类中不仅要负责对其直接基类进行初始化,还要负责对虚基类初始化
(3)为了保证虚基类在派生类中只继承一次,应当在该基类的所有直接派生类中声明为虚基类 ,否则仍然会出现对基类的多次继承。
*****************************************************************************
主定理:
T(n)=aT(n/b)+f(n)
(1):多项式小于: f(n)<n^logba
T(n)=O(n^logba)
(2): f(n)=n^logba
T(n)=O(n^logba * logn)
(3):多项式大于: f(n)>n^logba
T(n)=O(f(n))
************************************************************************************
多态:
定义:同样的命令对不同的对象有不同的行为
分为编译时的多态性和运行时的多态性
编译时多态可通过函数重载、模板实现
运行时多态可通过虚函数实现
多态存在的三个必要条件:
(1)要有继承
(2)重写(重写虚函数)
(3)父类引用指向子类对象(对象调用不满足此条件)
******************************************************************************
重写(覆盖)
重载
隐藏:
重载:只限于同级即在一个类中,函数名相同、形参个数、类型、const来重载
(重载机制)内部命名函数为:函数名_形参类型_形参类型
隐藏:子类与父类函数名相同就行,不需要考虑形参类型等
(覆盖后)子类只能看到子类同名的函数,要用 父类名:: 才能调用父类同名函数
重写:子类与父类函数名相同、形参类型、返回类型等相同,而且父类函数为虚(子类虚不 虚无所谓)(形参等不同或不虚则为覆盖)
一般情况:
函数不同名:父类看到自己函数,子类能看到父类和自己的函数
*************************************************************************************
虚函数
调用过程:
继承内存分配:父父父...类对象做成员变量 子(与多继承时构造函数调用相同)
存储为:虚函数表指针、成员变量、成员变量...
调用时:
指针类型为起始地址、函数为偏移量(与父类偏移量相同,多态子类函数地址覆盖父 类函数地址,加上偏移量就可实现多态)
***************************************************************************
柔性数组:
将数组声明为int a[]或者int a[0]放在结构体后,为柔性数组,数组不占空间
只允许有一个数组
***********************************************************************************