引用:
1,引用就是别名 (引用值的改变,其本身的值也会改变)
2,引用必须要初始化
3,也没有所谓的空引用
4,没有引用的引用。
int &x = a;
int &c = a; x和c 都是a的别名 所以 int &&c = x 是不行的
常引用(const):
-
const int &c = a
可以通过改变a的值而改变c
但不能改变c的值
int &b = a;
b += 10; 则 a =10 -
int a =10;
const int &b = a;
(可以通过)
const int a = 10;
int &b = a;
(不可以通过) 可以使程序的能力收缩而不能扩大
引用传递,形参的改变会改变实参
(inline)内联函数
调用的条件是程序中没有复杂的条件和循环语句。(为解决频繁调用小函数大量消耗栈空间的问题(开栈和清栈的开销,现场保护,现场恢复,涉及到终端以及陷入内核的问题))
比如:inline intMax(int a,int b)
{
return a+b;
}
处理方式:在函数调用点直接代码展开,不需要将实参压入栈中再处理函数体 -
内联函数和普通函数的区别:
1,资源开销和时间开销
2,内部结构的复杂程度 -
内联函数和static函数的区别:
-
内联函数和宏的区别:
1,处理的时间
2,编译期有安全检查,类型检查
3,内联函数是更安全的宏 -
使用场景:(必须是在release版本下才可以使用)
1.如果函数的执行开销小于开栈清栈开销,使用inline,因为函数体小,效率高(也就是函数功能单一)
2,反之使用普通函数,因为函数体大,空间利用率高内部结构复杂,函数的开销远远大于清栈和开栈的开销。
函数默认值
函数的默认值是从右向左依次给
int arc(int a , int b , int c = 0)
当有实参时,就将默认值进行替代(编译期进行)
例子:
arc(12,(23,34,45),56);
输出为 12,45,56;
函数的重载- 函数原型由,返回值类型,函数名,形参列表(类型,个数)
-
extern 关键字的使用:
-
extern “C” int Max(int a,int b)
外部关键字,此函数是其他工程中定义的函数(该函数以C语言的方式编写,因为C语言区分不同函数就是靠函数名,会将其他元素直接删除,将函数名变为_Max进行) -
重载的依据
-
返回类型不同(参数列表相同,是否可以重载(并且要考虑函数默认值))?
调用的二义性,当传入实参时,由于传入的实参的类型个数均相同,所以会出现计算机不知道给谁传值。 -
参数带有默认值的情况
-
为什么C++可以函数重载而C语言不可以?
因为该函数以C语言的方式编写,因为C语言区分不同函数就是靠函数名,会将其他元素直接删除,将函数名变为_Max进行 -
名字粉碎技术:C++
名字重命名 -
_stdcall调用约定:”?“标识函数名的开,后跟函数名
”@YG“标识参数列表的开始
”@Z“标识结束
@@YN 是C方式的调用约定
而C++将返回值类型,参数类型作为调用的一部分,如下图:
H表示函数和参数列表的类型
YA 表示C语言的调用约定
YG 表示C++的调用约定
不能因为函数传参造成函数的二义性
模板类型(主要处理函数重载概念)
语法:
template<class type>
template<typename Type>
template<struct T> //不能有结构体,为了区分C和C++
模板是产生代码的代码(编译时期)
void swap(type &a,type &b)
{
}
int main()
int a =10,b =20;
char s1=‘a’,s2= ‘b’;
swap(a,b);
swap(s1,s2);
根据swap中传入实参的类型,对函数进行重命名
typedef int Type;
void swap (Type&a , Type&b)
在编译期生成的代码的代码。
模板不是宏的替换而是重命名,如下