C++学习笔记7 C++函数的升级 上

来源:互联网 发布:日程管理 知乎 编辑:程序博客网 时间:2024/04/30 19:23

1:常量与宏回顾:

C++中的const常量可以替代宏参数定义;

const int a = 5  ; 等价于 # define a 5

宏具有副作用,那么C++是否有方法避免呢?

2:内联函数:

C++中推荐使用内联函数代替宏代码片段

C++中inline关键字声明内联函数

inline int func(int a, int b)

{

    return  (a < b ? a: b);

}

注意内联函数声明的时候inline关键字必须和函数定义在一起,否则编译器会直接忽略内链请求

 

关于内联函数:

C++可以将一个函数进行内联编译

被C++编译器内联编译的函数称为内联函数

内联函数在最终生成的代码中是没有定义的

C++编译器直接将函数体插入到函数调用的地方、

内联函数调用没有普通函数调用时的额外开销(压栈,跳转,返回)

C++编译器不一定准许函数的内联请求!

 

内联函数是一种特殊的函数,具有普通函数的特征(参数检查,返回类型等)
内联函数是对编译器的一种请求,因此编译器可能拒绝这种请求
内联函数由编译器处理,直接将编译后的函数体插入调用的地方
宏代码片段由预处理器处理,进行简单的文本替换,没有任何编译过程

 

现代C++编译器能够进行编译优化,因此一些函数即使没有
inline声明,也可能被编译器内联编译
 另外,一些现代C++编译器提供了扩展语法,能够对函数进行强
制内联
 如:g++中的__attribute__((always_inline))属性

 

使用内联函数有一定的限制:

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

       编译器对于内联函数的限制并不是绝对的,内联函数相对于普通函

数的优势只是省去了函数调用时压栈,跳转和返回的开销。因此,

当函数体的执行开销远大于压栈,跳转和返回所用的开销时,那么

内联将无意义

 

C++中内联函数实现机制:

inline int func(int a, int b)

{

    return  (a < b ? a: b);

}

int _tmain(int argc, _TCHAR* argv[])
{

 int r = func(1,2);   //int r =   return  (a < b ? a: b);

 return 0;
}

在C++中首先检查是否可以进行内联编译,如果编译器请求通过,那么内联函数func写入到符号表

当执行

 int r = func(1,2);

这句代码的时候,用符号表中的函数体直接替换func调用 int r =   return  (a < b ? a: b);

 

3:函数的默认参数:

C++中可以在函数声明时为参数提供一个默认值,当函数调

用时没有指定这个参数的值,编译器会自动用默认值代替

int mul(int x = 0); //函数声明时指定默认参数
int _tmain(int argc, _TCHAR* argv[])
{

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


 getchar();
 return 0;
}
int mul(int x)//定义的时候不再指定
{
 return x*x;
}

 

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

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

当b使用默认参数时,后面的c也必须使用默认参数

 

4:函数占位参数:

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

//函数占位参数
int add1(int a, int b, int )
{
 return a+b;
}

C++支持这样的函数占位参数
有什么意义?

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

eg:

在C语言中:

void func()

{};

调用的时候

func(1);

func(1,2);

在C语言中可行,在C++中编译不通过

但是

void func(int = 0)

{

}

func(1)就可以编译通过;

 

 

小结
 C++中可以通过inline声明内联函数
 内联函数在编译时直接将函数体插入函数调用的地方
 inline只是一种请求,编译器不一定允许这种请求
 内联函数省去了普通函数调用时压栈,跳转和返回的开销
 C++中在声明函数的时候指定参数的默认值
 C++可以声明占位符参数,占位符参数一般用于程序扩展
和对C代码的兼容

0 0