标准库输入输出
iostream包含了istream和ostream库,分别为输入和输出流
定义了四个IO对象:
cin输入,cin文件结束符为ctrl+z,然后enter;
cout输出
cerr输出警告和错误信息
clog输出程序运行的一般信息
引用和指针
引用
将声明符写成**&d**的形式来定义引用类型,d为声明的变量名
int value= 24;
int &revalue = value;//revalue是value的另一个名字
注意:
引用必须被初始化;
引用并非对象,对其进行的一切操作最终结果指向被引用的值,即value;
示例:
int i, & ii = i;
i = 5;
ii = 10;
此时i=ii=10;
指针
将声明符写成*d的形式来定义引用类型,d为声明的变量名
与引用不同;指针是对象,允许赋值,且无需初始化
获取对象的地址(取地址符&)
指针访问对象(*解引用符)
int ival =42;
int *p = &ival;
cout<<*p<<endl; //输出42
* p = 0;
cout<<*p<<";"<<ival << endl; //为指针赋值实际上是为其所指对象赋值,此时输出0,0;
注意:指针类型与所指对象数据类型必须相同;
指针必须初始化,定义一个空指针的方法
int *p1 = nullptr;
int *p2 = 0;
//include cstdlib;
int *p3=NULL; //不建议使用
指向数组的指针也可以看做迭代器
int arr[] = {0,1,2,3,4,5,6};
int *p=arr; //指的是arr[0]
++p; //此时指的是arr[1],arr[2]...
int n = arr.size();
int *e =&arr[n];
for(int *p=arr;p!=e;p++)
cout<<*p<<endl; //输出arr的全部元素
智能指针管理内存
运算符new分配内存;
int *pi = new int ; //指向一个动态分配的未初始化的无名对象,默认初始化,*pi的值未定义
int *pi = new int(); //值初始化为0;*pi为0;
int *pa = new int [10]; //10个未初始化的int
int *pa = new int [10](); //10个初始值为0的int
auto *pt = new auto(obj); //指向一个与obj类型相同的对象,并用obj进行初始化;
//可以选择直接初始化方式来创建指针并为其分配对象
int *pi = new int(102);
string *ps = new string(10,‘9’);
vector<int> *pv = new vector<int>{0,1,2,3,4,5,6};
运算符delete释放内存
delete p; //p必须指向一个动态分配的对象或是一个空指针
// 将相同的指针释放多次,行为是未定义的
int i,*pi1 = &i,*pi2 = nullptr;
double *pd = new double(33); *pd2 =pd;
delete i; //错误,i不是指针
delete pi1; //未定义:pi1指的是局部变量
delete pi2; //正确:释放空指针ok
delete pd; // 正确
delete pd2; //未定义:重复释放内存,会破坏自由空间
//为防止空悬指针,可以释放其所关联的内存
pd =nullptr; //指出pd不再绑定任何对象,所在在释放pd内存时,pd2也无效了
//释放动态数组
delete []pa;
普通指针和智能指针最好不要混用!
迭代器
使用迭代器进行二分法搜索(待刷题)
运算符
++i与i++的区别
int i=0,j;
j = ++i; //此时i=1;j=1;i先+再赋值给j
j = i++; //此时i=2;j=1;i先赋值给j再+;一般场景下不建议用
条件语句
if 语句根据条件决定控制流;
if(condition)
statement
else
statement2
switch根据表达式的值从几条执行路径选择一条;
...
switch(ch)
{
case"a": //case标签
case"o":
case"e":
case"e":
case"u":
++vowelCnt;
break;
default: ///对应的非case的标签
++otherCnt;
break;
}
for 循环
for(initializer;condition;expression) //括号内皆可省略
statement
范围for语句可以遍历容器所有元素
vector<int> v = {0,1,2,3,4,5,6};
for(auto &r:v)
r *=2;
///等价于
for(auto beg = v.begin(),end = v.end();beg!=end;++beg){
auto &r=*beg;
r *=2;
}
while 语句
只要条件为真,while就重复的执行循环体;
先检查条件,再执行循环体;
适用于不确定迭代次数的情况;适用于在循环结束后访问循环控制变量的情况;
while(condition)
statement
do while 语句
先执行循环体,再检查条件;至少执行一次循环
do
statement
while(condition);
跳转语句
break语句 适用于while,do while,for,switch,从这些语句的第一句开始继续执行;
continue语句 只能出现在for,while,do while语句的内部;switch只有嵌套在迭代语句内部时才能使用;
goto语句 使函数从goto语句无条件跳转到同一函数的另一个语句;(一般不建议使用)
异常处理
throw表达式包含关键字throw和一个表达式(表征函数异常异常类型);
throw runtime_error("失败报错"); //runtime_error定义在stdexcept头文件中
try语句块的通用语法形式
try{
program-statements
}catch(exception-declaration){
handler-statements
}catch(exception-declaration){
handler-statements
}
stdexcept 定义了一些标准的异常类。分为两大类:逻辑错误和运行时错误。
其中运行时错误是程序员不能控制的;
逻辑错误:
logic_error ——程序逻辑错误
domain_error ——参数对应的结果值不存在
future_error—— 未知错误
invalid_argument ——非法、无效参数
length_error ——创建对象超出最大长度
out_of_range ——访问超界
运行时错误:
runtime_error ——只有在运行时才能检测出的问题
range_error ——边界错误
overflow_error ——上溢
underflow_error ——下溢
system_error ——系统错误