内联函数
参数的引用传递
默认参数
函数重载
函数模板
内联(inline)函数
- 是C++为提高程序运行速度所做的一项改进(c语言中没有)
- 与常规函数的区别不在于编写方式
- 而在于被调用时的运行机制不同
- 编译器使用函数代码替换函数调用
-
~~如果执行函数代码的时间比处理函数调用机制的时间长,则节省的时间将只占整个过程的很小的一部分。不建议使用内联函数~~
常规函数:从函数那找到所在地址,使用他的地址
内联函数:直接把函数那的代码,复制–替换到main函数的地方 使用代码执行时间很短的时候
常规函数
内联函数
使用内联特性
关于C语言的内联函数的由来
#include <iostream>
#define N 5 //以后在使用N的所有场合,都会被自动替换成5
#define S(num) num * num //宏定义了一个S(sum)函数
//以后在使用S(num)的地方,就自动被替换成 num*num
using namespace std;
//内联 :替换
int main()
{
//5 + 10 * 5 +10
int result1 = S(5 + 10);
double result2 = S(2.5);
cout << result1 << endl;
cout << result2 << endl;
return 0;
}
使用了内联函数的:
引用
- 为对象起了另一个名字(引用即别名)
- 引用必须初始化,不可以直接引用常量(字面量) 例如~~:double & d = 12.3;~~d =111; (d的值被修改,违背了常量的概念)
可以使用 const double & d = 12.3;(指向常量的引用-合法的)
我们使用引用的时候,不需要测试其有效性。所以使用引用比指针的效率高一些。
两个数进行交换的实现3种方式
#include <iostream>
using namespace std;
void Swap1(int, int); //交换的是副本的值,不是原来的。与引用格式相同。。。
void Swap2(int*, int*);// 交换的是地址
void Swap3(int&, int&);//3与2号的实现是一样的,2用指针,3用引用
void Show( const int & , const int & );
int main()
{
int num1 = 10, num2 = 5;
Swap1(num1, num2);
cout << "执行后Swap1后:" << num1 << "\t" << num2 << endl;
Swap2(&num1,&num2); //直接传的是地址,。而函数只是把指针变了
cout << "执行后Swap2后:" << num1 << "\t" << num2 << endl;
Swap3(num1, num2);
cout << "执行后Swap3后:" << num1 << "\t" << num2 << endl;
Show(num1, num2);
cout << "执行后Show后:" << num1 << "\t" << num2 << endl;
return 0;
}
void Swap1(int num1, int num2)
{
int temp;
temp = num1;//传递的是整型的一块地址 直接换的是地址,就会改变其中的值
num1 = num2;
num2 = temp;
}
void Swap2(int*p1, int*p2)
{
int temp;
temp =* p1;//传递的是整型的一块地址 直接换的是地址,就会改变其中的值
*p1 = *p2;
*p2 = temp;
}
void Swap3(int & ref1, int &ref2)
{
//使用引用的理由:
//1.可以更加简便的书写代码
//2.可以直接传递某个对象,而不只是把对象复制一份
//3.风险是有可能被修改
//
int temp;
temp = ref1;
ref1 = ref2;
ref2 = temp;
}
void Show(const int & num1,const int & num2)
{
//我们希望显示函数中,只能实现传入参数的显示功能
//而禁止显示函数修改num1和num2的值(禁止函数内部修改引用参数值)
cout << "执行Swap后:" << "\t" << num2 << endl;
//num1 = 998;会对num出现修改 所以在开始引用时参数使用const
}
返回引用
函数返回引用类型
1.不要返回局部变量的引用 返回最后函数调用的值
2.函数可以不返回值,默认返回传入的引用对象本身 没有返回值,默认最后一个引用参数的值
3.返回引用时,要求函数参数中包含被返回的引用对象
**函数中的局部变量会被内存回收
所谓的内存回收,并不是把内存保存的设置清零,
而是指内存中你的程序申请的这块内存已经不是你的了
不要返回局部变量的引用**
输出结果是:
int &sum() //返回引用类型的函数
{
int num = 10;
//注意:rNum是在sum函数中定义的,所以叫局部变量
//rNum的生存期只在sum函数中!
int & rNum = num;
//函数中的局部变量会被内存回收
//所谓的内存回收,并不是把内存保存的设置清零,
//而是指内存中你的程序申请的这块内存已经不是你的了
//不要返回局部变量的引用
return rNum; //返回了一个局部引用类型变量(局部变量使用完之后是会被回收)
}
void test()
{
int x = 1;
int y = 2;
int z = 3;
}
int main()
{ //result在这里引用了一个局部变量
int & result = sum();
test(); //调用其他函数
cout << "result = " << result << endl;
return 0;
}
返回值只能是num1或者num2,不能返回第三个值num1 + num2
int &sum( int &num1, int &num2)
{
num1++;
num2++;
//num1++;
//没有返回值,默认最后一个引用参数的值
return num1; //返回值只能是num1或者num2,不能返回第三个值
}
int main()
{
int num1 =10, num2 = 15;
int &result =sum(num1,num2);
cout << "result = " << result << endl;
return 0;
}
int &sum( int &num)
{
num++;
//num1++;
//没有返回值,默认最后一个引用参数的值
return num; //返回值只能是num1或者num2,不能返回第三个值
}
int main()
{
int num =10;
int &result =sum(num);// result 是 sum的引用 ,result 和sum是一样的
sum(num) = 55;//修改sum的时候,result 也被修改了
cout << "result = " << result << endl;
return 0;
}
总结:使用引用参数小结
实操: 使用函数实现游戏中的私聊
默认参数
1.只能在定义或者声明中出现一个
2.从右向左添加默认值,先给c,再给b
错误。右边有默认值之后,才能有左边的默认值
test( ) 一个参数都不给,默认 1,5 , 10 ; test(1) 默认匹配 1; test(1,2) 默认匹配 1,5
函数重载
(overloading)
- 指可以有多个同名的函数
- 函数名相同,参数列表不同(特征标不同)
//重载-编译器在编译时,根据参数列表对函数进行重命名。
void Swap(int a, int b)
在编译器中,会重新命名为 Swap_int_int
void Swap(float a, float b)
在编译器中,会重新命名为 Swap_float_float
给什么类型的参数,就调用什么函数
重载决议----根据不同的类型参数,调用不同的函数
void Swap(int& a, int &b)
Swap_int_int // 和上面的那个重复
没有参数
有参数
有一个参数.
有多个参数
有歧义的不要放在一起,使用
call of overload ‘eating(std::string&)’ is ambiguous|
调用重载使调用是模糊的
实操:
#include <iostream>
using namespace std;
//使用重载实现数组的排序
//int iNums[] = {56,54,12,89,43};
//float fNum[] = {78.0f, 5.7f,42.8f, 99.1f};
//double dNums[] = {78.9,23.6,77.8,98.5,33.3};
void Sort(int[],int len);
void Sort(float[], int len);//重载:函数名相同,参数列表(特征标)不同
void Sort(double[], int len );
void Show(int[], int len);
void Show(float[], int len);
void Show(double[], int len);
int main()
{
int iNums[] = {56,54,12,89,43};
float fNum[] = {78.0f, 5.7f,42.8f, 99.1f};
double dNums[] = {78.9,23.6,77.8,98.5,33.3};
cout << "排序前:";
Show(iNums, sizeof(iNums)/ sizeof(iNums[0]));
Sort(iNums,sizeof(iNums)/ sizeof(int));
cout << "排序后:";
Show(iNums, sizeof(iNums)/ sizeof(iNums[0]));
return 0;
}
void Sort(int nums[], int len)
{
int temp;
sizeof(nums);
for(int i=0; i< len -1; i++)
{
for(int j = 0; j < len -i -1; j++)
{
if(nums[j] > nums[j+1])
{
temp = nums[j];
nums[j] = nums[j+1];
nums[j+1] =temp;
}
}
}
}
void Sort(float nums[], int len)
{
int temp;
for(int i=0; i< len -1; i++)
{
for(int j = 0; j < len -i -1; j++)
{
if(nums[j] > nums[j+1])
{
temp = nums[j];
nums[j] = nums[j+1];
nums[j+1] =temp;
}
}
}
}
void Sort( double nums[], int len)
{
int temp;
for(int i=0; i< len -1; i++)
{
for(int j = 0; j < len -i -1; j++)
{
if(nums[j] > nums[j+1])
{
temp = nums[j];
nums[j] = nums[j+1];
nums[j+1] =temp;
}
}
}
}
void Show(int nums[], int len)
{
for(int i=0; i< len -1; i++)
{
cout << nums[i] + ",";
}
cout << endl;
}
函数模板 Function Template
所谓函数模板,实际上就是建立一个 通用函数
- 函数定义时不指定具体的数据类型(使用虚拟类型代替)
- 函数被调用时编译器根据实参反推数据类型-类型的参数化
template
template 早期写法
函数模板和函数重载有不同的作用,不能替代啊。