C++函数调用那些事

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;
}

带默认值的函数的特点和优点:

  1. 给默认值时,从右往左给。
  2. 调用效率问题,直接使用默认值或者给定值,会比传变量的效率高一点。
  3. 定义处可以给形参默认值,声明也可以给形参默认值。
  4. 形参给默认值的时候,不管是定义出给,还是声明处给,形参默认值只能出现一次。(函数声明可以多次,但是定义只能有一次)
// 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;
}

函数重载

需要明白三个问题:

  1. C++为什么支持函数重载,而C语言不支持函数重载?
  2. 函数重载需要注意什么?
  3. C++和C语言代码之间如何互相调用?

问题一:C++为什么支持函数重载,而C语言不支持函数重载?

这是因为C++代码在编译函数产生符号的时候,函数是由 函数名+参数列表类型组成的。而C语言则是在编译函数产生符号的时候,函数是由 函数名组成的,所以在链接的时候无法根据参数列表类型实现重载。

C++中其实在编译的时候就确定了函数调用点执行函数重载的情况。

问题二:函数重载

  1. 一组函数,其中函数名相同,参数列表的个数或者类型不同,这一组函数就称作函数重载。
  2. 一组函数要称得上重载,那么一定是处于同一作用域当中的。
  3. const和volatile是怎么影响形参类型的。
  4. 一组函数,函数名相同,参数列表也相同,仅仅是返回值类型,那么不够成函数重载。

其实多态就是利用了函数重载的思想,多态又分为:静态多态(编译时期):函数重载;动态多态(运行时期)。

函数重载示例:

#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文件中的函数

  1. 在C++中引入C文件。
  2. 函数在声明。
extern "C" //让C++知道这个函数是C语言中定义的,否则就会出现无法解析外部命令,这是因为C/C++函数编译产生的函数符号不一样。
{
    
    
	int sum(int a,int b);
}

在C语言中调用C++的函数:

  1. 在C语言中引入C++文件。
  2. 修改C++中的函数形式。
#ifdef __cplusplus //__cplusplus是C++中自定义内容
extern "C" {
    
    
#endif  
	// 如果是C++文件,那就是用C的方式进行编译
	int sum(int a,int b)
	{
    
    
		return a+b;
	}
#ifdef __cplusplus
}
#endif

猜你喜欢

转载自blog.csdn.net/qq_45041871/article/details/132261559