C++函数调用
C++形参带默认值的函数
带默认值的形参必须从右往左给,给出以下实例:
int sum(int x;int y); //无默认值函数
int sum(int x;int y=0); //y有默认值
int sum(int x=0;int y=0); //x,y均匀默认值
int sum(int x=0;int y); //错误,不能x有默认值,而y没有默认值
函数调用过程和带默认值的区别:
int sum(int x = 0, int y = 0)
{
return x + y;
}
int main()
{
int a = 0;
int b = 10;
int ret = sum(a, b);
/*
mov ecx, dword ptr[ebp-8] //先将b移动入栈
push ecx
mov ecx, dword ptr[ebp-4]
push ecx
call sum
*/
cout << ret << endl;
ret = sum(a);
/*
push 0 //b默认为0
mov ecx, dword ptr[ebp-4]
push ecx
call sum
*/
ret = sum(); // 等价于sum(0,10);因为数字直接存放再内存中,所以直接可以调用。
/*
push 0 //b默认为0
push 0
call sum
*/
return 0;
}
带默认值的函数的特点和优点:
- 给默认值时,从右往左给。
- 调用效率问题,直接使用默认值或者给定值,会比传变量的效率高一点。
- 定义处可以给形参默认值,声明也可以给形参默认值。
- 形参给默认值的时候,不管是定义出给,还是声明处给,形参默认值只能出现一次。(函数声明可以多次,但是定义只能有一次)
// C++带有默认值参数的声明规则,形参默认值只能出现一次,不管是函数定义还是实现
int sum2(int x=10, int y=20);//函数声明
int sum2(int x, int y) {
return x + y; }//函数定义
int sum3(int x, int y = 20);
int sum3(int x = 10, int y);
int sum3(int x, int y) {
return x + y; };
int sum4(int x, int y);
int sum4(int x = 10, int y = 20) {
return x + y; }
更多c++ 函数声明与定义可以点击查看。
inline函数
inline内联函数和普通函数的区别?
inline内联函数:在编译过程中,就没有函数的调用开销了,在函数的调用点直接把函数的代码进行展开处理。
inline函数不在生成相应的函数符号。
但是不是所有的inline都会被编译器处理成内联函数(特别是递归函数不会内联,如果代码很多可能也会不内联)。如果函数经常使用,可以考虑作为内联函数。
debug版本,inline不会起作用,只能在release版本才能出现。
int sum(int x,int y){
return x+y;}
inline int sum2(int x,int y){
return x+y;}
int main()
{
int a=0,b=10;
int res=sum(a,b);
//这里是sum函数调用点,函数调用其实存在很多的过程,先将b,a一次压入函数栈中,
//在调用add函数进行计算,再将结果返回出来。在这个过程中函数执行了空间的开辟和回收,
//如果调用很多次就会有大量的空间开辟和回收开销,甚至这些开销远比功能的开销大,那么函数效率就很低。
int res=sum2(a,b);//调用内联函数,会直接将转化为res=a+b;就没有调用函数开销。
return 0;
}
函数重载
需要明白三个问题:
- C++为什么支持函数重载,而C语言不支持函数重载?
- 函数重载需要注意什么?
- C++和C语言代码之间如何互相调用?
问题一:C++为什么支持函数重载,而C语言不支持函数重载?
这是因为C++代码在编译函数产生符号的时候,函数是由 函数名+参数列表类型组成的。而C语言则是在编译函数产生符号的时候,函数是由 函数名组成的,所以在链接的时候无法根据参数列表类型实现重载。
C++中其实在编译的时候就确定了函数调用点执行函数重载的情况。
问题二:函数重载
- 一组函数,其中函数名相同,参数列表的个数或者类型不同,这一组函数就称作函数重载。
- 一组函数要称得上重载,那么一定是处于同一作用域当中的。
- const和volatile是怎么影响形参类型的。
- 一组函数,函数名相同,参数列表也相同,仅仅是返回值类型,那么不够成函数重载。
其实多态就是利用了函数重载的思想,多态又分为:静态多态(编译时期):函数重载;动态多态(运行时期)。
函数重载示例:
#include<iostream>
#include<string>
using namespace std;
// 下面三个同名的compare函数构成函数重载:
// 函数名相同,参数列表不同,在同一个作用域下
bool compare(int a,int b)
{
cout << "compare_int_int" << endl;
return a > b;
}
bool compare(double a,double b)
{
cout << "compare_double_double" << endl;
return a > b;
}
bool compare(char* a,char* b)
{
cout << "compare_char*_char*" << endl;
return strcmp(a, b);
}
// data存储在全局变量
int data = 10;
int main()
{
// 在局部作用域下定义compare,后面调用三个compare就会默认使用该局部作用域下的声明,
// 类型不匹配就会使用强制类型转化,类型转化不了就报错
// 所以要在同一作用域下才会构成函数重载
// bool compare(int a, int b);
compare(10, 20);
compare(10.0, 20.0);
compare("aaa", "bbb");
// data和全局变量data是可以重名的,因为作用域不同
int data = 20;
cout << data << endl;//20,优先使用该作用域下的值
cout << ::data << endl;//10,::函数作用域,使用全局变量的data
return 0;
}
问题三:C/C++代码怎么互相调用?
C++调用C文件中的函数
- 在C++中引入C文件。
- 函数在声明。
extern "C" //让C++知道这个函数是C语言中定义的,否则就会出现无法解析外部命令,这是因为C/C++函数编译产生的函数符号不一样。
{
int sum(int a,int b);
}
在C语言中调用C++的函数:
- 在C语言中引入C++文件。
- 修改C++中的函数形式。
#ifdef __cplusplus //__cplusplus是C++中自定义内容
extern "C" {
#endif
// 如果是C++文件,那就是用C的方式进行编译
int sum(int a,int b)
{
return a+b;
}
#ifdef __cplusplus
}
#endif