关键字
63个关键字
命名空间
作用:解决命名冲突
定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}中即为命名空间的成员---1.其中既可以放变量也可以放函数、2.命名空间可以嵌套、3.同一个工程中允许存在多个相同名称的命名空间,编译器后会合成同一个命名空间中。
命名空间的使用:
- N1::a 等等 (命名空间的名字::空间成员)
- 用using N1::b 后面直接用b
- 前面加using namespace N1; 将N1中的所有成员作为全局变量就直接用
namespace N1 // N1为命名空间的名称 { // 命名空间中的内容,既可以定义变量,也可以定义函数 int a; int Add(int left, int right) { return left + right; } }
注:在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污 染,namespace关键字的出现就是针对这种问题。
标准输入&标准输出
#include<iostream> C++头文件
cin、cout在std这个命名空间中,使用C++输入输出更方便,不需增加数据格式控制
注:输入:cin>>a>>endl;输出:cout<<a<<endl; cout<<10<<' '<<12.34<<'\n'
缺省参数
缺省参数是声明或定义函数时为函数的参数指定一个默认值。在调用该函数时,如果没有指定实参则采用该默 认值,否则使用指定的实参。
分类:
- 全缺省参数:void TestFunc(int a = 10, int b = 20, int c = 30)
- 半缺省参数:void TestFunc(int a, int b = 10, int c = 20)
注意:
1. 半缺省参数必须从右往左依次来给出,不能间隔着给
2. 缺省参数不能在函数声明和定义中同时出现,如果声明与定义位置同时出现,恰巧两个位置提供的值不同,那编译器就无法确定到底该用那个缺省值。
3. 缺省值必须是常量或者全局变量
4. C语言不支持(编译器不支持)
引用(别名):给变量一个别的名字,共用一个内存空间,类似于绰号
概念:
比如:李逵,在家称为"铁牛",江湖上人称"黑旋风"。
类型& 引用变量名(对象名) = 引用实体; int& ra = a 注意:引用类型必须和引用实体是同种类型的
特性:
1. 引用在定义时必须初始化
2. 一个变量可以有多个引用。
3. 引用一旦引用一个实体,再不能引用其他实体
常引用:
const int a = 10; //int& ra = a; // 该语句编译时会出错,a为常量 const int& ra = a; const int& b = 10; double d = 12.34; //int& rd = d; // 该语句编译时会出错,类型不同 const int& rd = d; //进行了隐式类型转换:申请一个 int型 临时变量之后,给rd //临时变量具有常性 //rd指向的空间就是那个临时变量的空间
使用场景:
1. 做参数 void Swap(int& left, int& right) { int temp = left; left = right; right = temp; } 2. 做返回值 int& TestRefReturn(int& a) { a += 10; return a; }
注意:如果函数返回时,离开函数作用域后,其栈上空间已经还给系统,因此不能用栈上的空间作为引用类型返回。如果以引用类型返回,返回值的生命周期必须不受函数的限制(即比函数生命周期长)。不能引用函数的局部变量。不能返回函数栈上的空间,函数结束,函数的栈就没了。(函数栈帧问题)
int& add(int a, int b) { int c = a + b; return c; } int main(){ int &ret = add(1, 3); cout << "add(1,3)" << ret << endl; } //结果 ret 是随机值。不是 4 。
传值:
传值方式,在函数调用过程中会生成一份临时变量用形参代替,最终把实参的值传递给新分配的临时变量即形参。
优缺点:
优点:实参不会被污染改变。
缺点:改变不了外部实参,当实参数量过大时,效率低,生成大量临时变量。
传地址:
优点:对参数的改变可以体现在外部实参上,当实参数据量过大时,传址效率高。
缺点:不安全,容易被改变。
//传值,传地址,传引用
void swap1(int a, int b)
{
int temp = a;
a = b;
b = temp;
}
void swap2(int& ra, int& rb)
{
int temp = ra;
ra = rb;
rb = temp;
}
void swap3(int* pa, int* pb)
{
int temp = *pa;
*pa = *pb;
*pb = temp;
}
int main(){
int a = 10;
int b = 20;
swap1(a, b); //传值
swap2(a, b); //传引用
swap3(&a, &b); //传地址
}
传值,传引用,传地址的效率比较
以值作为参数或者返回值类型,在传参和返回期间,函数不会直接传递实参或者将变量本身直接返回,而是传递实参或者返回变量的一份临时的拷贝,因此用值作为参数或者返回值类型,效率是非常低下的,尤其是当参数或者返回值类型非常大时,效率就更低。
传引用与传址差不多,速率远大于传值。
问题:指针和引用有什么区别?
相同点:
底层的实现方式相同,都是按照指针的方式来实现的。
不同点:
- 引用在定义时必须初始化,指针没有要求。
- 一旦一个引用被初始化为指向一个对象,就不能再指向其他对象,而指针可以在任何时候指向任何一个同类型对象。
- 没有NULL引用,但有NULL指针。
- 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址*空间所占字节个数。
- 引用自加改变变量的内容,指针自加改变了指针指向。
- 有多级指针,但是没有多级引用。
- 指针需要手动寻址,引用通过编译器实现寻址。
- 引用比指针使用起来相对更安全。