C++--第3课 - 函数的升级-上

第3课 - 函数的升级-上

1. 常量与宏回顾

C++中能够的const常量可以代替宏常数定义,如:

const int A = 3; #define A 3

在C++中的解决方案是代替宏代码片段,宏代替代码片段可以避免宏的副作用。

2. 内联函数

(1)C++中推荐使用内联函数代替宏代码片段。C++中使用inline关键字声明内联函数

inline int func(int a, int b)

{

return a < b ? a : b;

}

内联函数声明时inline关键字必须和函数定义结合在一起,否则编译器会直接忽略内敛请求。

(2)C++编译器可以将一个函数进行内敛编译。被C++编译器内敛编译的函数叫做内联函数。

内联函数在最终生成的代码中是没有定义的。C++编译器直接将函数体插入函数调用的地方。内敛函数没有普通函数调用时候的额外开销(压栈,跳转,返回)。但是,C++编译器不一定会准许函数的内链请求。

(3)内联函数是一种特殊的函数,具有普通函数的特征(参数检查,返回类型等)。内联函数是对编译器的一种请求,因此编译器可能拒绝这种请求。内敛函数由编译器处理,直接将编译后的函数体插入到调用的地方。然而,宏代码片段由预处理器处理,进行简单的文本变换,没有任何的编译过程。现在的C++编译器能够进行编译优化,因此一些函数即使没有inline声明,也能被编译器内联编译。另外,一些现代的C++编译器提供了扩展语法,能够对函数进行强制内联。

#include <stdio.h>

#define FUNC(a, b) ((a) < (b) ? (a) : (b))

inline int func(int a, int b)

{

    return a < b ? a : b;

}

int main(int argc, char *argv[])

{

    int a = 1;

    int b = 3;

    int c = func(++a, b);

   

    printf("a = %d\n", a);

    printf("b = %d\n", b);

    printf("c = %d\n", c);

   

    printf("Press enter to continue ...");

    getchar();

    return 0;

}

(4)C++中内联函数的限制

不能存在任何形式的循环语句,不能存在过多的条件判断语句,函数体不能过于庞大,不能对函数进行取地址操作,函数的内联声明必须在调用语句之前。

编译器对内联函数的限制并不是绝对的,内联函数相对于普通函数的优势只是省去了函数调用时候的压栈,跳转和返回的开销。因此,当函数体的执行开销远大于压栈。跳转和返回所用的开销时,那么内联将变得无意义。

(5)内联函数的实现机制

3. 函数的默认参数

C++中可以在函数声明时为参数提供一个默认值,当函数调用时没有指定这个参数的值,编译器会自动用默认值代替。

#include <stdio.h>

int mul(int x = 3);  //声明的时候指定默认的参数值。

int main(int argc, char *argv[])

{

    printf("mul(2) = %d\n", mul(2));

    printf("mul(-2) = %d\n", mul(-2));

    printf("mul() = %d\n", mul());

   

    printf("Press enter to continue ...");

    getchar();

    return 0;

}

int mul(int x)     //定义时不再指定。

{

    return x * x;

}

l  函数默认参数而定规则。

只有参数列表后面部分的参数才可以提供默认的参数值,一旦在一个函数调用中开始使用默认的参数值,那么这个参数后的所有的参数都必须使用默认的参数值。

#include <stdio.h>

int add(int a, int b = 0, int c = 0, int d = 0)

{

    return a + b + c;

}

int main(int argc, char *argv[])

{

    printf("add(2) = %d\n", add(2));

    printf("add(1, 2) = %d\n", add(1, 2));

    printf("add(1, 2, 3) = %d\n", add(1, 2, 3));

   

    printf("Press enter to continue ...");

    getchar();

    return 0;

}

4. 函数占位参数

在C++中可以为函数提供占位参数,占位参数只有参数类型声明,而没有参数名声明。一般的情况下,在函数体内部无法使用占位参数。

#include <stdio.h>

int func(int a, int b, int)

{

    return a + b;

}

int main(int argc, char *argv[])

{

    printf("func(1, 2, 3) = %d\n", func(1, 2, 3));

   

    printf("Press enter to continue ...");

    getchar();

    return 0;

}

l  意义:

可以将占位参数与默认参数结合起来使用,为以后的程序扩展留下线索,兼容C语言程序中可能出现的不规范写法。

#include <stdio.h>

int func(int a, int b, int = 0)

{

    return a + b;

}

int main(int argc, char *argv[])

{

    printf("func(1, 2) = %d\n", func(1, 2));

   

    printf("Press enter to continue ...");

    getchar();

    return 0;

}

小结:

C++中可以通过inline声明内联函数。

内联函数在编译时直接将函数体插入函数调用的地方。

inline函数只是一种请求,编译器不一定允许这种请求。

内联函数省去了普通函数调用时候的压栈。跳转和返回的开销。

C++中声明函数的时候指定参数的默认值。

C++可以声明占位符参数,占位符参数一般用于程序扩展和对C代码的兼容。

猜你喜欢

转载自www.cnblogs.com/free-1122/p/11336154.html