函数详细解析

目录

形参有默认值的函数

基本概述

指令角度

设定形参默认值

内联函数

基本概述

代码段

函数重载

答疑解惑


形参有默认值的函数

基本概述

从右向左设定形参默认值

形参默认值可以在定义时设定,也可以在声明时设定

每个形参的默认值只能被设定一次

指令角度

#include
using namespace std;

int sum(int a = 10, int b = 20)
{
    return a + b;
}

int main()
{
    int a = 10;
    int b = 20;

    int ret = sum(a, b);
    /*
    mov eax, dword ptr[ebp-8]
    push eax
    mov ecx, dword ptr[ebp-4]
    push ecx
    call sum
    */

    ret = sum(a);
    /*
    push 14H
    mov ecx, dword ptr[ebp-4]
    push ecx
    call sum
    */

    ret = sum();
    /*
    push 14H
    push 0Ah
    call sum
    */

    return 0;
}

设定形参默认值

#include
using namespace std;

// int sum(int a = 10, int b)
// {
//     return a + b;
// }
// 违背基本概述中的“从右向左设定形参默认值”,错误!

int sum(int a, int b = 20)
{
    return a + b;
}
// 遵循基本概述中的“从右向左设定形参默认值”,正确!

int main()
{
    int a = 10;
    int b = 20;

    int ret = sum(a, b);
    cout << "ret:" << ret << endl;

    return 0;
}
#include
using namespace std;

// int sum(int a, int b = 20);
// int sum(int a, int b = 20);
// 违背基本概述中的“每个形参的默认值只能被设定一次”,错误!

int sum(int a, int b = 20);
int sum(int a = 10, int b);
// 注意!这是正确的写法!
// 遵循基本概述中的“从右向左设定形参默认值”,正确!

int main()
{
    int a = 10;
    int b = 20;

    int ret = sum(a, b);
    cout << "ret:" << ret << endl;

    return 0;
}

int sum(int a, int b)
{
    return a + b;
}

内联函数

基本概述

关键字为inline

内联函数不会生成相应的函数符号

inline在debug版不发挥作用,在release版才发挥作用

使用关键字inline仅仅表示建议编译器将该函数当作内联函数,如果函数很复杂,编译器仍然将其视为普通函数

不是所有使用关键字inline的函数都被处理成内联函数,例如,递归函数不会被处理成内联函数

普通函数与内联函数的区别

调用普通函数有调用开销

内联函数在编译阶段将函数在调用点进行展开处理,省去了函数调用开销

代码段

#include
using namespace std;

inline int sum(int x, int y)
{
    return x + y;
}

int main()
{
    int a = 10;
    int b = 20;

    int ret = sum(a, b);
    cout << "ret:" << ret << endl;
    
    return 0;
}

函数重载

答疑解惑

函数重载的含义

一组重载函数一定是处在同一作用域中

一组重载函数,函数名相同,参数的个数或类型不同

函数重载是静态(编译时期)多态的一种

// 以下代码用于演示一组函数不在同一作用域导致无法构成重载的情况,同时产生错误

#include
#include
using namespace std;

bool compare(int a, int b)
{
    cout << "bool compare(int a, int b)" << endl;
    return a > b;
}

bool compare(double a, double b)
{
    cout << "bool compare(double a, double b)" << endl;
    return a > b;
}

bool compare(const char * a, const char * b)
{
    cout << "bool compare(const char * a, const char * b)" << endl;
    return strcmp(a, b) > 0;
}

int main()
{
    bool compare(int a, int b);
    // 因为此处对compare(int, int)的声明
    // 导致compare(int, int)处在局部作用域
    // 而compare(double, double)和compare(char *, char *)处在全局作用域
    // 不满足“一组重载函数一定是处在同一作用域中”这一条件,无法重载!

    bool b1 = compare(10, 20);
    bool b2 = compare(10.10, 20.20);
    bool b3 = compare("abcd", "efgh");

    cout << b1 << endl << b2 << endl << b3 << endl;

    return 0;
}

 函数详细解析_第1张图片

// 以下代码用于演示正确的函数重载

#include
#include
using namespace std;

bool compare(int a, int b)
{
    cout << "bool compare(int a, int b)" << endl;
    return a > b;
}

bool compare(double a, double b)
{
    cout << "bool compare(double a, double b)" << endl;
    return a > b;
}

bool compare(const char * a, const char * b)
{
    cout << "bool compare(const char * a, const char * b)" << endl;
    return strcmp(a, b) > 0;
}

int main()
{
    bool b1 = compare(10, 20);
    bool b2 = compare(10.10, 20.20);
    bool b3 = compare("abcd", "efgh");

    cout << b1 << endl << b2 << endl << b3 << endl;

    return 0;
}

 函数详细解析_第2张图片

为什么C++支持函数重载,C语言不支持函数重载?

C++代码产生的函数符号由函数名和参数类型组成,多个重载函数产生互不相同的函数符号,可以通过链接

C代码产生的函数符号只由函数名决定,多个相同的函数符号将导致链接错误

函数重载的注意事项有哪些?

const、volatile关键字对形参类型的影响

函数名和参数列表相同、返回值不相同的函数不存在重载关系

C++和C语言代码如何互相调用函数?

因为C++和C语言生成函数符号的规则不同,所以C++和C语言代码无法直接互相调用

无论C++调C,还是C调C++,都需要在C++中使用extern "C" { },extern "C" { }只能被C++识别!

extern "C" { }使得C++编译器按照C语言的规则来生成{ }中函数的符号

// extern "C" { }的灵活运用

#ifdef __cplusplus
extern "C"
{
#endif
    int sum(int a, int b)
    {
        return a + b;
    }
#ifdef __cplusplus
}
#endif

你可能感兴趣的:(C++,c++,函数,内联,重载)