从C到C++ | C++入门(二)

目录

缺省参数

1.)全缺省

 2.)半缺省

函数重载 

1.) 参数类型不同

2.) 参数个数不同

3.) 参数顺序不同 

函数重载的原理:

!!!注意  !!!

引用

1.) 引用做参数

2.) 引用做返回值

引用和指针的区别:


缺省参数

        顾名思义,就是函数的参数可以缺省,即我们在写函数的声明或定义的时候,可以让其参数有默认值。起作用是,在调用函数的时候,如果我们没有指定实参,则会采用该形参的缺省值。

        例子:

#include <iostream>
using namespace std;

//形参n的缺省值10,若没有指定实参,则实参n的值为10
void test(int n = 10)
{
    cout << "n :" << n << endl;
}
int main() 
{
    test();
    test(1);
    return 0;
}

         输出结果:

缺省参数有以下几种:

1.)全缺省

     顾名思义,全缺省的意思则是函数参数全部都有缺省值。

// 形参a 和形参b 都有缺省值
void test(int a = 10, int b = 20)
{
    cout << "a: " << a << endl;
    cout << "b: " << b << endl;
}

 2.)半缺省

        顾名思义,则是函数参数部分有缺省值,但是要注意的是,半缺省则必须从右往左开始。

// 形参a 没有缺省值,形参b 有缺省值
void test(int a, int b = 20)
{
    cout << "a: " << a << endl;
    cout << "b: " << b << endl;
}

        为什么半缺省必须从右往左开始缺省?以下代码则可以解释

// 这是个错误的例子,从左往右开始缺省
void test(int a = 10, int b)
{
    cout << "a: " << a << endl;
    cout << "b: " << b << endl;
}

         上述错误的例子,该如何调用函数test()?

        假设我们都有指定的参数,test(1,2),这个没问题,实参a = 1, b = 2。

那,如果我们要采用形参的缺省值,使 a 采用缺省值10,b 的值为20 的话,是test(20),那这个20按照函数参数的定义顺序的话,是赋给a,而参数b则没有收到指定的值,则会出现错误。


函数重载 

        在学习C++的过程中,会经常遇到的知识点就是重载,其是C++的精华之一,可以说“不了解重载则是不了解C++”。函数重载是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的 参数个数 或 类型 或 类型顺序 不同。

1.) 参数类型不同

        例子:

#include <iostream>
using namespace std;

//参数类型不同 
int Add(int num1, int num2)
{
    cout << " Add(int num1, int num2) " << endl;
    return num1+num2;
}

double Add(double num1, double num2)
{
    cout << " Add(double num1, double num2) " << endl;
    return num1+num2;
}

int main()
{
    // 参数是两个int类型,调用Add(int num1, int num2)
    Add(1,2);
    
    // 参数是两个double类型,调用double Add(double num1, double num2)
    Add(2.5,2.5);

    return 0;
}

        结果:

2.) 参数个数不同

        例子:

#include <iostream>
using namespace std;

// 参数个数不同
void test()
{
    cout << " test() " << endl;
}

void test(int a)
{
    cout << " test(int a) " << endl;
}

int main()
{
    // 参数个数为0,调用函数test()
    test();

    // 参数个数为1,调用函数test(int a)
    test(0);    

    return 0;
}

        结果:

3.) 参数顺序不同 

        例子:

#include <iostream>
using namespace std;

// 参数顺序不同
void test(int a, double b)
{
    cout << " test(int a, double b) " << endl;
}

void test(double a, int b)
{
    cout << " test(int a, double b) " << endl;
}

int main()
{
    // 参数顺序为 int double,调用函数test(int a, double b)
    test(1,2.0);

    // 参数顺序为 double int,调用函数test(double a, int b)
    test(1.0,2);

    return 0;
}

        结果:

函数重载的原理:

        重载函数在编译的汇编阶段会生成一个自己的符号表,在不同环境下生成的符号表不同,例如在g++环境下,以void test(int a, double b)为例,会生成一个为<_z4testid>的符号表,其中4是函数名的长度,test为函数名,id为形参的类型及顺序。

!!!注意  !!!

        因符号表中并不能区别函数的返回值的类型,因此函数的返回值的类型不同并不能构成函数重载!函数重载的构成的条件是 参数个数 或 类型 或 类型顺序 不同!!!


引用

        引用是给已存在对的变量取一个别名,而不是新定义一个变量,编译器不会为引用变量开辟内存空间,它和引用的变量共用同一块内存空间,因此,在某些场景下,我们可以采用引用来直接对变量的值进行修改,这种方式比采用指针的方式方便。

        例子:

void test()
{
    int a = 10;
    int& ra = a;    //ra引用变量a
    cout << " a: " << a <<endl;
    cout << " ra: " << ra << endl;
    ++ra;       //实际是对变量a进行修改
    cout << " a: " << a << endl;
    cout << " ra: " << ra << endl;
}

        结果:

        在使用引用的时候,要注意权限不能放大。例如引用一个const修饰的常变量时,要给const修饰引用。

void test()
{
    const int a = 10;
    // int& ra = a; 该语句编译时会出错,权限放大了
    const int& ra = a;
}

        引用有多种使用场景,例如做函数参数以及返回值等等。

1.) 引用做参数

// 引用做参数,效果类似指针,直接访问实参所在的内存空间
void Swap(int& num1, int& num2)
{
    int tmp = num1;
    num1 = num2;
    num2 = tmp;
}

2.) 引用做返回值

// 引用做返回值
int& SelfIncrease(int& num)
{
    return ++num;
}

         在使用引用做返回值的时候,要注意返回的对象的生命周期是否在函数作用域之外,若返回的对象的生命周期不在函数作用域之外,则不该采用引用的方式。

//正确的例子
int& Count()
{
    static int n = 0;
    ++n;
    return n;
}

// 错误的例子
int& Add(int a, int b)
{
    int c = a + b;
    return c;
}

        以值作为参数或者返回值类型,在传参和返回期间,函数不会直接传递实参或者将变量本身直接返回,而是传递实参或者返回变量的一份临时的拷贝,因此用值作为参数或者返回值类型,效率低下,尤其是当参数或者返回值类型非常大时,效率就更低。

        而采用引用做参数或者返回值,在传参和返回期间,函数会直接传递参数或者变量的本身,效率得到了提高。

引用和指针的区别:

        引用在语法概念上引用就是一个别名,没有独立空间,和其引用实体共用同一块空间
        引用在底层实现上实际是有空间的,因为引用是按照指针方式来实现的。

        引用在概念上定义一个变量的别名,而指针是存储一个变量的地址,因此没有NULL引用,但是有NULL指针。

        引用在定义的时候必须初始化,而指针没有要求。

        引用在初始化引用了一个变量后,就不能再更改引用别的变量,而指针可以在任何时候指向任何同一个类型的变量。

        在sizeof操作符中,引用的结果为引用类型的大小,而指针始终是地址空间所占字节数(4/8)。

        引用没有多级引用,而指针有多级指针。

  • 14
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

福楠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值