Skip to content

C++ 函数

提前封装好的,可重复使用的,完成特定功能的独立代码单元

函数还有很多叫法,比如方法、子例程或程序,等等。

定义函数

C++ 中的函数定义的一般形式如下:

cpp
return_type function_name( parameter list ) { 
	body of the function;
	return return_type;
}

在 C++ 中,函数由一个函数头和一个函数主体组成。下面列出一个函数的所有组成部分:

  • 返回类型: 一个函数可以返回一个值。return_type 是函数返回的值的数据类型。有些函数执行所需的操作而不返回值,在这种情况下,return_type 是关键字 void

  • 函数名称: 这是函数的实际名称。函数名和参数列表一起构成了函数签名。

  • 参数: 参数就像是占位符。当函数被调用时,您向参数传递一个值,这个值被称为实际参数。参数列表包括函数参数的类型、顺序、数量。参数是可选的,也就是说,函数可能不包含参数。

  • 函数主体: 函数主体包含一组定义函数执行任务的语句

函数的默认参数

基本语法:

cpp
返回值类型 函数名(参数 = 默认值)
{
	函数体
}

1.函数默认参数==后==的参数必须都要有默认值

cpp
#include <iostream>  
using namespace std;  
  
int func(int a, int b = 0, int c = 1)  //int b= 0 后面必须都有默认参数
{  
cout << "a=" << a << endl;  
cout << "b=" << b << endl;  
cout << "c=" << c << endl;  
return a+b+c;  
}  
int main() {  
int a = 10;  
int b = 20;  
int c = 30;  
  
cout << func(a, b) << endl;  
  
return 0;  
}

输出

a=10
b=20
c=1
31

2.声明和实现只能有一个有默认参数

cpp
int func(int a, int b = 0, int c = 1);  //声明有默认参数
  
int main() {  
int a = 10;  
int b = 20;  
int c = 30;  
  
cout << func(a, b) << endl;  
  
return 0;  
}  
  
int func(int a, int b, int c)       //实现没有默认参数
{  
cout << "a=" << a << endl;  
cout << "b=" << b << endl;  
cout << "c=" << c << endl;  
return a+b+c;  
}

函数声明

函数声明会告诉编译器函数名称及如何调用函数。函数的实际主体可以单独定义。

函数声明包括以下几个部分:

cpp
return_type function_name( parameter list );

针对上面定义的函数 max(),以下是函数声明:

cpp
int max(int num1, int num2);

在函数声明中,参数的名称并不重要,只有参数的类型是必需的,因此下面也是有效的声明:

cpp
int max(int, int);

当您在一个源文件中定义函数且在另一个文件中调用函数时,函数声明是必需的。在这种情况下,您应该在调用函数的文件顶部声明函数。

函数分文件编写

1.函数头文件
cpp
#include <iostream>  
using namespace std;  
  
//头文件  
//写函数声明  
	void swap(int a , int b);
2.函数体文件
cpp
//包含“swap.h”的头文件告诉编译器配套  
#include "swap.h"  
  
//源文件  
// 写函数主体  
void swap(int a, int b)  
{  
	int temp = b;  
	b = a;  
	a = temp;  
	  
	cout << "swap a=" << a << " ";  
	cout << "swap b=" << b << endl;  
}
main文件
cpp
#include <iostream>  
using namespace std;  
  
//导入自定义头文件,""表示自定义头文件  
#include "swap.h"  
  
int main()  
{  
	int a = 10;  
	int b = 20;  
	cout << "a=" << a << " ";  
	cout << "b=" << b << endl;  
	  
	swap(a,b);  
	  
	cout << "a=" << a << " ";  
	cout << "b=" << b << endl;  
	return 0;  
};

调用函数

创建 C++ 函数时,会定义函数做什么,然后通过调用函数来完成已定义的任务。

当程序调用函数时,程序控制权会转移给被调用的函数。被调用的函数执行已定义的任务,当函数的返回语句被执行时,或到达函数的结束括号时,会把程序控制权交还给主程序。

调用函数时,传递所需参数,如果函数返回一个值,则可以存储返回值。例如:

实例

cpp
#include <iostream> 
using namespace std; 

// 函数声明 
int max(int num1, int num2); 

int main () { 
	// 局部变量声明 i
	nt a = 100; 
	int b = 200; 
	int ret; 

	// 调用函数来获取最大值 
	ret = max(a, b); 
	cout << "Max value is : " << ret << endl; 
	return 0; 
} 

// 函数返回两个数中较大的那个数 
int max(int num1, int num2) { 
	// 局部变量声明 
	int result; 
	if (num1 > num2) 
		result = num1; 
	else
		result = num2; 
	return result; 
}

把 max() 函数和 main() 函数放一块,编译源代码。当运行最后的可执行文件时,会产生下列结果:

Max value is : 200

函数参数

调用类型描述
传值调用该方法把参数的实际值赋值给函数的形式参数。在这种情况下,修改函数内的形式参数对实际参数没有影响。
指针调用该方法把参数的地址赋值给形式参数。在函数内,该地址用于访问调用中要用到的实际参数。这意味着,修改形式参数会影响实际参数。
引用调用该方法把参数的引用赋值给形式参数。在函数内,该引用用于访问调用中要用到的实际参数。这意味着,修改形式参数会影响实际参数。

1.传值调用

这个版本看似能够交换两个整数的值,但实际上它不能达到预期的效果。由于它使用值传递,函数内部的交换只影响局部变量的副本,不会影响原始变量的值。这个函数在实际应用中无法实现交换变量的目的。

cpp
void swap(int x, int y) {
    int temp = x;
    x = y;
    y = temp;
}

2.指针调用

这个版本通过指针传递参数。调用这个函数时,你需要传递变量的地址。这种方式也可以交换两个整数的值,但使用指针使得代码略显复杂,且需要处理空指针等安全问题。

cpp
void swap(int* x, int* y) {
    int temp = *x;
    *x = *y;
    *y = temp;
}

3.引用调用

这个版本的 swap 使用引用传递,实际上交换了两个整数变量的值。这是最常见的 swap 函数形式,因为它确保了传递给函数的实际参数会被交换。

cpp
void swap(int& x, int& y) {
    int temp = x;
    x = y;
    y = temp;
}

参数的默认值

当您定义一个函数,您可以为参数列表中后边的每一个参数指定默认值。当调用函数时,如果实际参数的值留空,则使用这个默认值。

这是通过在函数定义中使用赋值运算符来为参数赋值的。调用函数时,如果未传递参数的值,则会使用默认值,如果指定了值,则会忽略默认值,使用传递的值。请看下面的实例:

实例

cpp
#include <iostream> 
using namespace std; 

int sum(int a, int b=20) { 
	int result; 
	result = a + b; 
	return (result);
}

int main () {
	// 局部变量声明
	int a = 100; 
	int b = 200; 
	int result; 
	
	// 调用函数来添加值 
	result = sum(a, b); 
	cout << "Total value is :" << result << endl; 
	
	// 再次调用函数 
	result = sum(a); 
	cout << "Total value is :" << result << endl; 
	
	return 0; 
}

当上面的代码被编译和执行时,它会产生下列结果:

Total value is :300
Total value is :120

Lambda 函数与表达式

C++11 提供了对匿名函数的支持,称为 Lambda 函数(也叫 Lambda 表达式)。

Lambda 表达式把函数看作对象。Lambda 表达式可以像对象一样使用,比如可以将它们赋给变量和作为参数传递,还可以像函数一样对其求值。

Lambda 表达式本质上与函数声明非常类似。Lambda 表达式具体形式如下:

cpp
[capture](parameters)->return-type{
	body
}

例如:

cpp
[](int x, int y){ return x < y ; }

如果没有返回值可以表示为:

cpp
[capture](parameters){body}

例如:

cpp
[]{ ++global_x; }

在一个更为复杂的例子中,返回类型可以被明确的指定如下:

cpp
[](int x, int y) -> int { int z = x + y; return z + x; }

本例中,一个临时的参数 z 被创建用来存储中间结果。如同一般的函数,z 的值不会保留到下一次该不具名函数再次被调用时。

如果 lambda 函数没有传回值(例如 void),其返回类型可被完全忽略。

在Lambda表达式内可以访问当前作用域的变量,这是Lambda表达式的闭包(Closure)行为。 与JavaScript闭包不同,C++变量传递有传值和传引用的区别。可以通过前面的[]来指定:

cpp
[]      // 沒有定义任何变量。使用未定义变量会引发错误。
[x, &y] // x以传值方式传入(默认),y以引用方式传入。
[&]     // 任何被使用到的外部变量都隐式地以引用方式加以引用。
[=]     // 任何被使用到的外部变量都隐式地以传值方式加以引用。
[&, x]  // x显式地以传值方式加以引用。其余变量以引用方式加以引用。
[=, &z] // z显式地以引用方式加以引用。其余变量以传值方式加以引用。

另外有一点需要注意。对于[=][&]的形式,lambda 表达式可以直接使用 this 指针。但是,对于[]的形式,如果要使用 this 指针,必须显式传入:

[this]() { this->someFunc(); }();

评论区

欢迎留言、补充或勘误。

xiaoba.blog