C++ 入门学习 09 函数进阶

内联函数
参数的引用传递
默认参数
函数重载
函数模板

内联(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 早期写法

函数模板和函数重载有不同的作用,不能替代啊。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值