C++入门篇——深入C++基础语法(二)

C++入门篇——深入C++基础语法(二),第1张

C++入门篇——深入C++基础语法(二)

C++是结构化和模块化的语言,适合处理较小规模的程序。对于复杂的问题,规模较大的程序,需要高度抽象和建模时,C语言则不合适。为了解决软件危急,20世纪80年代,计算机界提出了OOP(面向对象)思想,支持面向对象的程序设计语言应运而生。

本篇将为大家介绍C++的基础语法,由于C++向下兼容C语言的大多数语言特性,对于一些C语言已具备的语法,将不做论述

前文索引:

C++入门篇——深入C++基础语法(一)

目录

三、缺省参数

缺省参数的概念

缺省参数的分类

四、函数重载

函数重载的概念

名字修饰


三、缺省参数 缺省参数的概念

缺省参数是在函数声明或定义时,为函数的参数设置一个默认值。

在调用这个函数时,如果使用者没有对其特定参数进行传参,则该参数将采用其默认值。

如下便是为函数指定了一个缺省参数:

void func(int a = 1)
{
    cout << a << endl;
}

我们不对其进行传参,直接调用,就会输出默认值:

int main()
{
    func();

    return 0;
}
缺省参数的分类 全缺省参数

所谓全缺省参数,即为所有的参数设置了缺省值:

void func(int a = 1, int b = 2, int c = 3)
{
    cout << a << endl;
    cout << b << endl;
    cout << c << endl;
}

在调用函数时,可以不传任何参数,此时所有参数都使用指定的实参。

当然,也可以部分传参,但必须满足“不能跳跃传参的原则”,即传过去的参数必须是从左向右连续的。

针对上述函数,有以下4种传参方式:

int main()
{
    func();
    cout << endl;
    func(0);
    cout << endl;
    func(0,0);
    cout << endl;
    func(0,0,0);
    cout << endl;

    return 0;
}

输出结果如下:

半缺省参数

半缺省参数,即缺省部分参数,正确设置半缺省参数有两个原则:

1、必须从右向左缺省

2、必须连续缺省

因此如果想将上面的函数转化为半缺省,只有两种情况,即:

void func(int a, int b = 2, int c = 3)
{
    cout << a << endl;
    cout << b << endl;
    cout << c << endl;
}
void func(int a, int b, int c = 3)
{
    cout << a << endl;
    cout << b << endl;
    cout << c << endl;
}

同时,缺省参数不能在函数声明和定义中同时出现,否则编译器不能够确定采取哪个缺省值。

四、函数重载 函数重载的概念

在同一作用域中,C++允许同时声明几个功能类似的同名函数,这样的函数即为重载函数。

要构成重载函数,它们的形参列表(参数个数或类型或顺序)必须不同,常用来处理实现类似而数据不同的问题。

以下函数互为重载函数:

void print(int a)
{
    cout << a << endl;
}

void print(float a)
{
    cout << a << endl;
}

void print(int a, float b)
{
    cout << a << b << endl;
}

void print(float a, int b)
{
    cout << a << b << endl;
}

注:只有返回值不同的函数不能构成重载,原因是在调用时编译器无法区分,存在歧义。

名字修饰

那么为什么C++支持函数重载,而C语言不支持呢?或者说C++是如何支持函数重载的呢?要弄清楚这个问题,就要了解一下C++的名字修饰。

在此之前,先梳理一下C/C++中程序运行所要经历的几个阶段:预处理、编译、汇编、链接。

预处理:头文件的展开、宏替换、条件编译、去注释等

编译:检查语法,生成汇编代码

汇编:将汇编代码转换为二进制的机器码

问题的关键就在于链接。

我们先来看看vs2019下C语言的名字修饰规则

int main()
{
    func();

    return 0;
}

直接运行会报错:

 可以看到这里的 _func就是修饰过后的名称。

如果在C语言中写入两个函数名相同的函数,它们的名称都将被修饰为_func,此时在链接时,编译器就不知道该填入哪个函数的地址,因为它们的名字修饰完全相同。

再来看看C++:

int main()
{
    func(1);
    func(1, 1);

    return 0;
}

 可见名字的修饰就复杂了许多,两个重载函数的名字修饰各不相同,因此在链接时,编译器可以根据不同的名字修饰,得到对应函数的正确地址。

总结:C++的目标文件符号表不是直接用函数名来表示和查找函数的。

1、函数名修饰规则,不同编译器不同

2、有了函数修饰规则,只要参数不同,符号表里重载的函数就不存在二义性和冲突了,连接查找重载函数的地址时,也是明确的了

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5702525.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存