C++输入&输出
使用cout标准输出(控制台)和cin标准输入(键盘)时,必须包含头文件以及std标准命名空间。
#include
using namespace std;
在std命名空间下,为了和C头文件区分,也为了正确使用命名空间,规定C++头文件不带.h;
//输入
cin
//>> 输入运算符
cin>>b>>c //cin在输入时,遇到空格/换行则输入结束,多余输入的在之后的cin时继续读取,而不会在需要输入
//输出
cout
//<< 输出运算符
cout<<b<<" "<<c<<endl; //endl 换行符
命名空间
目的: 是对标识符的名称进行本地化,以避免命名冲突或名字污染
关键字: namespace
命名空间的定义
// 命名空间中的内容,既可以定义变量,也可以定义函数
//1. 普通的命名空间
namespace N1 // N1为命名空间的名称
{
int a;
int Add(int left, int right)
{
return left + right;
}
}
//2. 命名空间可以嵌套
namespace N2
{
int a;
int b;
int Add(int left, int right)
{
return left + right;
}
namespace N3
{
int c;
int d;
int Sub(int left, int right)
{
return left - right;
}
}
}
//3. 同一个工程中允许存在多个相同名称的命名空间,编译器后会合成同一个命名空间中。
命名空间的使用
//1.加命名空间名称及作用域限定符
N::a
//N 命名空间名称
//:: 作用域限定符
//a 变量名
N1::N2::a //命名空间嵌套使用
//2.使用using将命名空间中成员引入
using N::b; //声明
b //直接调用,相当于全局变量
//3.使用using namespace命名空间名称引入
using namespce N; //直接导出命名空间
//命名空间中的所有成员都相当于全局变量(除嵌套命名空间中的变量)
//会与程序中所定义的同名变量冲突
//using是引入某个变量,using namespace直接引入整个命名空间
缺省参数
定义: 缺省参数是声明或定义函数时为函数的参数指定一个默认值。在调用该函数时,如果没有指定实参则采用该默认值,否则使用指定的实参。
//全缺省参数 每个参数都带缺省值
void TestFunc(int a = 10, int b = 20, int c = 30)
//半缺省参数 部分参数带有缺省值(缺省值必须从右往左一次赋值)
void TestFunc(int a, int b = 10, int c = 20)
//缺省参数不能在函数声明和定义中同时出现
//传参时必须传递没有缺省值的参数
//缺省必须是常量或全局变量
函数重载
定义: 函数重载是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 顺序)必须不同,常用来处理实现功能类似数据类型不同的问题
条件:
- 必须在相同的作用域
- 函数的名字必须相同
- 参数列表不同(参数类型、参数个数、参数类型次序不同)
支持函数重载的原理
//编译器:vs2013
//C语言中,编译器对函数名的修饰规则
//函数名前加下划线
//c++中,编译器对函数名字的修饰规则
//把参数的类型编译到函数名中
?Add @ @YA HHH @Z
函数名 函数名结束 后面跟函数参数列表(函数参数+返回类型) 返回值类型+参数列表类型 参数列表的类型结束
//N double //H int
c++中使用c语言来编译函数
extern "C" int Add(int left, int right); //支持跨平台
引用
定义: 给已存在变量取了一个别名(编译器不会为引用变量开辟内存空间,引用与引用的变量共用同一块内存空 间。)
引用特性
- 引用在定义时必须初始化
- 一个变量可以有多个引用
- 引用一旦引用一个实体,再不能引用其他实体(引用变量确定后不能改变)
语法
//类型& 引用变量名(对象名) = 引用实体;
int & ret = a;
//& 引用标志,只有在与类型在一起时才能成为引用
//引用是给变量起别名,变量必须存在
//引用的类型与变量的类型相同
常引用——const类型的引用
const int a = 10; //常量
//int& ra = a; // 该语句编译时会出错,a为常量
const int& ra = a; //必须在在类型前加const
// int& b = 10; // 该语句编译时会出错,10为常量
const int& b = 10;
int b = 10;
const int& rb = b;
b = 20;
//直接修改b后,rb一起变化
//rb = 20; // 该语句编译时会出错,const修饰引用,表示引用为常量,不可以改变
double d = 12.34;
//int& rd = d; //该语句编译时会出错,类型不同
const int& rd = d; //可能会存在数据的丢失
//加上const后可以通过编译,且直接修改d后,rd并未改变
//原因:d与rd并未使用同一块空间,d与rd的类型不同(所占字节不同),直接赋值不安全,编译器会创建一个int临时变量,拷贝d中的内容,rd引用临时变量,所以const int& 可以引用
//添加const,临时变量具有常属性,不允许修改
使用场景
- 函数的参数
- 函数的返回值函数的返回值
//简单实例
//主函数中连续三次打印函数内变量
int& Add()
{
int ret = 10;
return ret;
}
int main()
{
int& a = Add();
printf("%d ", a);
printf("%d ", a);
printf("%d ", a);
return 0;
}
//打印错误,栈空间会随着函数的结束而被系统收回
//如果函数返回时,离开函数作用域后,其栈上空间已经还给系统,因此不能用栈上的空间作为引用类型返回。如果以引用类型返回,返回值的生命周期必须不受函数的限制(即比函数生命周期长)。
指针与引用的区别
在语法概念上引用就是一个别名,没有独立空间,和其引用实体共用同一块空间。
在底层实现上实际是有空间的,因为引用是按照指针方式来实现的
- 引用在定义时必须初始化,指针没有要求
- 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型实体
- 没有NULL引用,但有NULL指针
- 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占 4个字节)
- 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
- 有多级指针,但是没有多级引用
- 访问实体方式不同,指针需要显式解引用,引用编译器自己处理
- 引用比指针使用起来相对更安全(不需要判断空指针)
内联函数
定义: 以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数压栈的开销, 内联函数提升程序运行的效率。
关键字: inline
特性
- inline是一种以空间换时间的做法,省去调用函数额开销。所以代码很长或者有循环/递归的函数不适宜使用作为内联函数。
- inline对于编译器而言只是一个建议,编译器会自动优化,如果定义为inline的函数体内有循环/递归等等,编译器优化时会忽略掉内联
inline int Add(int left, int return);
auto关键字(c++11)
作用: 占位符,编译器自动检测变量始化类型替换auto(编译阶段) 不再表示自动变量
使用规则:
- 使用auto定义变量时必须对其进行初始化
- 用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&
- 当使用auto在同一行声明多个变量时,这些变量必须是相同的类型
- auto不能作为函数函数的参数类型(不一定每个参数都有缺省值,实参传递时类型无法保证),不能声明数组(无法推断数组的类型)
- auto不能定义类的非静态成员变量
- 实例化模板时不能使用auto作为模板参数
优点:
- 复杂类型变量声明时的简化 (命名空间)
- 免除程序员在一些类型声明时的麻烦或错误
auto a = 100; //int a = 100;
//auto b; //auto定义的变量必须进行初始化
cout<<typeid(a).name()<<end1 //查看变量的类型 a 变量名
基于范围的for循环
使用条件: for循环后的括号由冒号“ :”分为两部分:第一部分是范围内用于迭代的变量, 第二部分则表示被迭代的范围,
- 范围必须具体确定 。(自定义类型,必须提供begin和end的 方法,begin和end就是for循环迭代的范围)
- 迭代的对象要实现++和==的操作
空指针nullptr
关键字,代表空指指针
原因: 编译器NULL与0会出现歧义调用,NULL会被当作0处理
保留NULL原因: 兼容,c98无法通过编译
类型: nullotr_t nullptr的类型
总结
- 在使用nullptr表示指针空值时,不需要包含头文件,因为nullptr是C++11作为新关键字引入的。
- 在C++11中,sizeof(nullptr) 与 sizeof((void*)0)所占的字节数相同。