第二章
2.2
- decltype(x) y; //声明y变量的数据类型与x相同
- 声明命名常量时必须赋初始
- 转义字符(见下表)
- bool型变量的输出
如果直接输出,显示结果为1或0;
bool b=true;
cout<<b<<endl; //显示结果为1
如果要输出true或false,可使用操纵符boolalpha;
bool b=true;
cout<<boolalpha<<b<<endl; //显示内容为true
- 类型定义:
typedef 数据类型 数据类型的别名;
eg.
typedef long long ll; //定义ll为长整数型
- c++运算符和优先级:
2.3
- 求余运算符(%)
除数和被除数必须都是整数
一般情况下,a%b的结果符号与a相同
- 自增/减运算符
int a=1,b,c;
b=a++; //先赋值后自增
//b=1 a=2;
a=1;
c=++a; //先自增后赋值
//c=2 a=2;
- 位运算符
1.移位
b=a<<c; //b=a*2^c;
b=a>>c; //b=a/2^c;
2.按位求反
b=~a;
3.与运算
b=a&c;
4.或运算
b=a|c;
5.异或运算
b=a^c;
相关位运算常用技巧:
1.减位/加位
去掉最后一位 a>>1
在最后加一个0 a<<1
在最后加一个1 a<<1+1
去掉末尾起第一个1的左边 a & (a ^ (a-1))
2.变位
把最后一位变成1 a|1
把最后一位变成0 a|1-1
最后一位取反 a^1
把末尾第k位变成1 a | ( 1<<(k-1) )
把末尾k位变成1 a | (1<<k-1)
把末尾起第一个0变成1 a | (a+1)
把末尾第k位变成0 a & ~( 1<<(k-1) )
把末尾连续的1变成0 a&(a+1)
把末尾连续的0变成1 a|(a-1)
末尾第k位取反 a ^ ( 1<<(k-1) )
末尾k位取反 a ^ (1<<k-1)
3.取位
取末一/二/三位 a&1 / a&3 / a&7
取末k位 a & ( (1<<k)-1 )
取右数第k位 a>>(k-1)&1
取末尾连续的1 ( a^(a+1) )>>1
取末尾起第一个1所在位置 a&-a
4.判断奇偶
(a&1)==1 奇数
(a&1)==0 偶数
相关实例应用:位运算
- 长度运算符
sizeof(数据类型名) - 显式(强制)类型转换
static_cast<类型名>(表达式)
注:指针类型之间的转换用reinterpret_cast<类型名>(表达式)
eg.
int a=2,b=3;
(a+b)/2 = 2;
static_cast<double>(a+b)/2 = 2.5;
2.4
- switch语句
switch(表达式)
{
case 常量表达式1:语句1
case 常量表达式2:语句2
...
case 常量表达式n:语句n
default:语句n+1
}
2.5
- 常用操纵符
重点:fixed / setprecision(n)
2.6
- 声明指针变量
数据类型 *指针变量名;
- 使用指针之前必须初始化
只能给指针赋予三种类型
1.NULL (指针不指任何对象)
int *p=NULL;
2.同类型对象的地址
int x,*p;
p=&x;
3.同类型的指针
int x,*p1,*p2;
p1=&x;
p2=p1;
- &与*互为逆运算 x等价于 * &x
- 通用指针 (void类型 即空类型)
不同类型的指针不能直接赋值
int a,*pInt;
double *pDouble;
pDouble=reinterpret_cast<double *>(pInt);
- 可以使用const修饰指针来保护数据,防止数据被非法修改
const的位置决定了谁是常量
1.const在*右边
int x=1,y=2;
const int * pInt=&x;
const修饰指针指向的变量,指针指向变量的值不可修改,指针本身的值可修改
pInt是指向int型常量的指针
pInt所指向的变量的值为常量,即x的值
若要修改,可以使指针指向其他变量来修改 eg.pInt=&y;
2.const在*左边
int * const pInt=&x;
const修饰指针本身,指针指向变量的值可修改,指针本身的值不可修改
pInt是一个指向int型变量的常量指针
若要修改,可以修改指针指向变量的值 eg.*pInt=3;
3.const同时出现在指针运算符*的左右边
const int * const pInt=&x;
const既修饰指针指向变量,也修饰指针本身,指针指向变量的值和指针本身的值都不可修改
第三章
3.2 内联函数
针对短小函数,函数调用时间远远大于函数执行时间,因此可以使用内联函数提高代码执行效率。
本质:编译时不会直接调用,而是将内联函数的代码直接复制到使用处
使用:内联函数一定要短小 ,在普通函数的基础上在最前面加上inline即可
eg.
inline double area(double x)
{
return x*x;
}
3.3 函数默认参数
...
double area(double r=1) //1即为area函数的默认参数,当没有给参数时就使用1
{
const double pi=3.14;
double area1=0;
if(r>0) area1=pi*r*r;
return area1;
}
int main()
{
cout<<area()<<endl; //输出3.14 没有参数输入 默认为1
cout<<area(2)<<endl; //输出12.56
}
...
3.4 函数重载
- c++中允许出现在同个作用域中的多个函数 具有相同名字 但参数不同 。这种机制称为函数重载,这些函数称为重载函数。
- 为了保证函数的唯一性,c++要求重载函数具有不同的签名(函数名、参数个数、类型、顺序),但不能通过返回值类型加以区分。
3.5 函数模板
- 泛型函数
声明
template<typename T> //T为类型参数
以编写最大值函数为例
T maxvalue(T num1,T num2) //maxvalue是一个函数模板
{ //函数返回值和两个参数的数据类型都是泛型 适用于所有数据类型
return (num1>num2)?num1:num2;
}
函数模板可以有多个类型参数,所有类型参数都放在尖括号内
eg. <typename T1, typename T2>
3.7 指针和函数
- 指针作为函数参数
eg.
void swap(int *x,int *y)
{
int temp;
temp=*x;
*x=*y;
*y=temp;
}
- 指针作为函数返回值
eg.
int *max(int *x,int *y)
{
return (*x>*y)?x:y;
}
3.8 引用和函数
如果变量需要占用大量的内存空间,那么传递变量值效率较低,使用引用更高效
void swap(int &x,int &y)
{
int temp;
temp=x;
x=y;
y=temp;
}
3.9 Lambda表达式
- Lambda表达式是匿名函数,可以在需要时便捷创建函数
- []是Lambda表达式的导入符,Lambda表达式可以有参数和返回值
auto square=[](int x)->int
{ //↑形参 ↑函数类型
return x*x;
};
cout<<square(7)<<endl; //输出49
- Lambda表达式可以不通过形式参数表而直接捕获(使用)与其位于同一作用域内的外部变量
- [] 不捕获任何外部变量
- [ = ] 值传递 捕获所有外部变量(只能读取不能修改,或者修改了也是修改的副本,本身不变)
- [x,&y] 值传递捕获x , 引用传递捕获y
[=,&x] 值传递捕获除x外所有外部变量,引用传递捕获x
[&,x] 引用传递捕获除x外所有外部变量,值传递捕获x - 语法
[捕获变量表](形式参数表)->函数类型
{
函数体
}
3.10 异常处理
int main()
{
...
try(
if(...)
throw ...; //抛出异常
...
)
catch(...){ //捕获异常
... //处理异常
}
//如果没有异常跳过catch块往下执行
...
}
3.11 使用标准库
- 终止程序的两种方法:
return语句(当且仅当由main函数调用才终止程序)
return 表达式;
exit函数(不管哪个函数调用都有效)
exit(表达式);
exit(EXIT_SUCCESS); //表示程序正常终止
exit(EXIT_FAILURE); //表示程序异常终止 - 随机数
cout<<RAND_MAX<<endl;
//RAND_MAX是cstdlib头文件中声明的常量,在不同计算机、操作系统、编译器下,其值可能不同
//一般为32767
for(int i=1;i<=10;i++)
cout<<rand()<<endl;
//生成的随机数都小于RAND_MAX
要使每一遍随机数不同,需要改变种子值,通过cstdlib中的srand函数来改变种子值
unsigned int seed;
cin>>seed;
srand(seed);
for(int i=1;i<=0;i++)
cout<<rand()<<endl;
这样随着种子值输入不同,输出的随机数也不同
最简单的方法使用time函数返回当时时间来作为种子值,保证每次运行时产生不同的随机数序列
srand(time(NULL)); //返回当时时间
产生范围[a,b]范围内的随机数
a+rand()%(b-a+1)
3.12 程序结构
- 静态变量和动态变量
用static关键字声明的变量是静态变量
int x;
static y;
x是动态变量,y是静态变量
- 其他看书 略
第四章
4.1 一维数组
- 数组初始化
const int maxn=3;
//一般用命名常量来指定数组长度
int a[maxn];
int b[3]={0,1,2}; //b[0]=0,b[1]=1,b[2]=2
int c[4]={4,5}; //c[0]=4,c[1]=5,c[2]=0,c[3]=0
//初始值个数可以小于数组长度,从头依次初始化数组元素为对应值,剩余元素初始化为0
- 数组作为函数参数
eg.交换两数组的值
const int maxn=10;
int a[maxn],b[maxn];
...(赋值)
void(int a[],int b[])
{
int temp;
for(int i=0;i<maxn;i++)
{
temp=a[i];
a[i]=b[i];
b[i]=temp;
}
}
4.2 二维数组
- 初始化
声明二维数组时,可以使用嵌套的形式来初始化
int a[3][2]={ {1,2}, {3,4}, {5,6} };
或
int a[3][2]={1,2,3,4,5,6};
a[0][0]=1 a[0][1]=2
a[1][0]=3 a[1][1]=4
a[2][0]=5 a[2][1]=6
(迷宫问题中常用以嵌套形式表示方向)
也可以部分初始化,同理一维数组
int a[3][2]={0};
或
int a[3][2]={};
以上都表示全部初始化为0
4.3 指针和数组
int a[10];
int *p=a; 等价于 int *p=&a[0];
使用指针变量访问数组元素:
下标法 p[i]即为a[i];
指针法 *(p+i)即为a[i]
4.4 排序和查找
- 二分查找函数binary_search ----> c++ stl binary_search函数
4.5 array数组
4.6 动态内存分配
- 使用new和delete运算符实现动态内存分配
c++ new和delete的用法
new的使用格式:因为new出来的是一段空间的首地址,所以一般需要用指针来存放这段地址。
第五章~第九章
自行写代码(略)