C++基础知识之函数2

电子说

1.3w人已加入

描述

内联函数

在C++中,我们可以使用inline关键字来定义内联函数。内联函数是一种特殊的函数,它在编译时会被直接嵌入到调用它的代码中,从而避免了函数调用的开销,提高了程序的执行效率。内联函数的定义通常比较短小,否则它的嵌入代码会导致程序的体积增大,从而降低程序的性能。另外,内联函数的使用也不是万能的,它只适用于一些简单的函数,对于复杂的函数,我们还是应该使用普通的函数。

使用和定义

在C++中,我们可以使用inline关键字来定义内联函数。内联函数的定义通常放在头文件中,以便在多个源文件中使用。下面是一个简单的内联函数的例子:

inline int max(int a, int b) {
    return a > b ? a : b;
}

在上面的例子中,max函数是一个内联函数,它的定义前面有inline关键字。当我们在程序中调用max函数时,编译器会将其直接嵌入到调用它的代码中,从而避免了函数调用的开销。

优点

  • 提高程序的执行效率。由于内联函数在编译时会被直接嵌入到调用它的代码中,从而避免了函数调用的开销,因此可以提高程序的执行效率。
  • 可以避免一些函数调用带来的问题。例如,函数调用会导致一些寄存器的值被保存和恢复,从而影响程序的执行效率。而内联函数的嵌入代码可以避免这些问题。

缺点

  • 可能会导致代码体积增大。由于内联函数的嵌入代码会被直接嵌入到调用它的代码中,因此可能会导致代码体积增大,从而降低程序的性能。
  • 可能会导致代码重复,效率降低。由于内联函数的嵌入代码会被直接嵌入到调用它的代码中,因此可能会导致代码重复,可能会导致编译时间增加。

constexpr函数

在C++11中,我们可以使用constexpr关键字来定义constexpr函数。constexpr函数是一种特殊的函数,它在编译时就能够计算出结果,从而可以用于一些需要在编译时确定的场合。

❝需要注意的是,constexpr函数的定义和使用有一些限制,例如它的返回值类型必须是字面值类型,它的参数和函数体必须是常量表达式等等。

constexpr函数的定义和使用

在C++11中,我们可以使用constexpr关键字来定义constexpr函数。下面是一个简单的constexpr函数的例子:

constexpr int factorial(int n) {
    return n <= 1 ? 1 : n * factorial(n - 1);
}

在上面的例子中,factorial函数是一个constexpr函数,它的定义前面有constexpr关键字。当我们在程序中调用factorial函数时,编译器会在编译时就计算出结果,从而可以用于一些需要在编译时确定的场合。

优点

  • 在编译时就能够计算出结果,从而可以用于一些需要在编译时确定的场合,可以提高程序的执行效率。
  • 由于constexpr函数的定义通常比较简单,因此可以在头文件中定义,从而方便其他文件的使用。

缺点

  • 定义和使用有一些限制。由于constexpr函数的定义和使用有一些限制,因此不能在所有的场合都使用constexpr函数。
  • 函数通常需要在编译时计算出结果,因此可能会增加代码量。 为什么会增加代码量呢,例如,在下面的代码中,我们定义了一个constexpr函数factorial,它的定义比较简单,但是在编译时会生成一些额外的代码:
constexpr int factorial(int n) {
    return n <= 1 ? 1 : n * factorial(n - 1);
}

int main() {
    std::cout << factorial(5) << std::endl;
    return 0;
}

在上面的代码中,编译器会在编译时生成一些额外的代码,用于计算factorial(5)的结果。这些额外的代码可能会增加程序的代码量,从而影响程序的可读性和维护性。因此,在使用constexpr函数时,需要权衡代码量和执行效率之间的关系,选择合适的方案。

函数指针

在C++中,函数指针是一种指向函数的指针,它可以用于调用函数或者作为函数的参数和返回值。函数指针的类型由函数的返回值类型和参数类型决定,例如,下面是一个函数指针的定义:

int (*p)(int, int);

在上面的代码中,我们定义了一个函数指针p,它指向一个返回值类型为int,参数类型为int和int的函数。

函数指针的使用

函数指针可以用于调用函数或者作为函数的参数和返回值。例如,下面是一个使用函数指针的例子:

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

int sub(int a, int b) {
    return a - b;
}

int calc(int (*p)(int, int), int a, int b) {
    return p(a, b);
}

int main() {
    int a = 1, b = 2;
    int c = calc(add, a, b);
    int d = calc(sub, a, b);
    std::cout << c << std::endl; // 输出 3
    std::cout << d << std::endl; // 输出 -1
    return 0;
}

在上面的代码中,我们定义了两个函数add和sub,它们分别用于求两个整数的和和差。然后,我们定义了一个函数calc,它有三个参数:一个函数指针p,两个整数a和b。calc函数的作用是调用函数指针p,并将a和b作为参数传递给它。在main函数中,我们使用calc函数来计算两个整数的和和差,并输出结果。

除了回调函数,函数指针还可以用于实现函数对象和函数指针数组。函数对象是一种类对象,它重载了函数调用运算符operator(),从而可以像函数一样被调用。函数指针数组是一种数组,它的元素是函数指针,可以用于实现多态和动态调用等功能。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分