运算符
::——域作用限定符,限定符前方为空时,找全局。例如:printf("%D\n", ::a);
<<——流插入运算符,cout<<a,意思就是把a的值输出出去
cout——流输出 cin——流输入,这两者都可以自识别数据类型
1、namespace——命名空间域,在命名空间域里的变量只影响使用范围,不影响生命周期(即仍然随着函数的消亡而消亡)。例如:
namespace wlw1
{
struct Node*
{
int val;
int* next;
}
}
namespace wlw2
{
struct Node*
{
int val;
int* next;
}
}
int main()
{
//此处建立变量时,可以通过访问不同的命名空间域来建立不同空间域的变量
struct wlw1::Node a;
struct wlww::Node b;
return 0;
}
命名空间可以可以多层嵌套,例如:
namespace wlw1
{
namespace wlw2
{
struct Node*
{
int val;
int* next;
}
}
}
int main()
{
//此处建立变量时,可以通过访问不同的命名空间域来建立不同空间域的变量
struct wlw1::wlw2::Node a;
return 0;
}
命名空间域的使用:1)指定命名空间访问;2)全局展开(一般情况不建议用);3)部分展开(即对常用的函数进行全局展开,比如c++里std库里的cout和endl)
2、缺省参数——声明一个函数时,需要传递参数,此时可以对这个传递参数进行初始值设定,当调用此函数时没有传参数值过来,就以初始值进行函数运行。例如:
void A(int a=0)
{
a=a+1;
printf("%d\n",a);
}
int main()
{
A(1);
A();
}
//此时计算出来的两个值分别为2和1,有传递的参数,用传递的参数;没有的就用初始设定的参数
如果声明的函数中有不止一个参数,则使用缺省参数时,只能从最后一个函数开始使用,不能第一个参数使用的是缺省参数,后面的用的是传参。例如:
void A(int a=10,int b=20,int c=30)
{
a=a+1;
printf("%d\n",a);
}
int main()
{
//可以使用
A(1,2,3);
A(1,2,);
A(1,,);
A();
//不可使用
A(,2,);
}
3、函数重载——对于功能相似的函数因为参数类型不同,参数个数不同,参数类型顺序不同,可以进行函数重载,用同一个函数名进行声明。(在同一个作用域才能生效)
例如:
int add(int a,int b)
double add(double a,double b)
void f(int a,int b)
void f(inta)
void f(int a,char b)
void f(char a,int b)
因为函数名都一样,所以调用起来十分方便,不用每个不同的函数都要起一个不同的名字。
在调用时能够精准的寻找到每个不同的函数是因为在编译时,编译器会对函数名进行一定程度的修饰,例如:函数int add(int a,int b)的函数名修饰为addii,在调用时通过参数的不同来选择不同的函数(不同的开发软件使用的编译器不同,修饰规则也不一样)。
4、引用——相当于对变量取别名,例如:
int i=0;
int& k=i;
其中k和i就是同一个变量,地址一样,只是名字不同。
1)定义时必须初始化
2)引用不能改变指向,因为就是同一个变量——所以不能做链表中的next指针
应用:1)做参数
2)做返回值(优点:1、减少拷贝;2、调用者可以修改返回对象)——限制:做的返回值需要出了作用域仍然存在(即函数调用完成需销毁后,仍然存在)
指针和引用,在初始化或者赋值后,权限可以缩小,不能放大。
引用和指针的不同点:
1)引用概念上定义一个变量的别名(不另开辟空间),指针存储一个变量地址(需要空间存储地址);
2)引用在定义时必须初始化,指针没有要求;
3)引用在初始化指向一个实体后,就不能再引用其他实体;而指针可以指向相同类型的不同实体;
4)没有NULL引用,但是有NULL指针;
5)使用sizeof函数时,引用结果为引用的数据类型的大小,而指针是地址的大小,在32位平台下大小都为4字节;
6)引用自加一是引用的实体数据加一,指针则是向后移动一个数据类型大小的距离;
7)有多级指针,没有多级引用;
8)访问实体方式不同,指针需要解引用,引用编译器自己处理;
9)引用比指针使用起来相对安全。
5、 内联函数
关于宏——c++常用const和enum来代替宏常量,用inline(内联函数)代替宏函数
宏本身缺点:1)不能调试;2)没有安全类型检查;3)有些场景非常复杂,容易出错
宏是一种非常暴力的替换,也没有安全类型检查,非常容易出错
内联函数是在正常的函数声明前加一个 inline ,即可成为内联函数,内联函数在编译阶段就会消失,在每个调用它的地方直接按函数的定义进行编译,而不是跳转到函数内进行运行。
例如:有一个普通函数和一个内联函数,都是有十行代码,在主函数里分别调用了这两个函数各1000次,在编译后普通函数运行的指令数为10+1000,而内联函数则是10*1000。
所以内联函数是一种以空间换时间的战术(空间是指编译后的空间),特别适合小函数(通常来说是十行左右的函数)。
内联函数声明和定义不能想其他函数一样分离(即声明在头文件,定义在cpp文件),分离会导致函数无法展开。