根据下列代码和结果回答下列问题。
代码
// Created by 黑马程序员.
#include "iostream"
using namespace std;
void switch_num(int a, int b)
{
int tmp = a;
a = b;
b = tmp;
}
void switch_num_pointer(int *a, int *b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
int main()
{
int x = 1;
int y = 2;
switch_num(x, y);
cout << "x=" << x << endl;
cout << "y=" << y << endl;
switch_num_pointer(&x, &y);
cout << "x=" << x << endl;
cout << "y=" << y << endl;
return 0;
}
结果:
D:\CLion_code\cmake-build-debug\CLion_code.exe
x=1
y=2
x=2
y=1
Process finished with exit code 0
函数体由哪5部分组成呢?这5部分的作用是什么呢?函数的实参和形参分别是什么呢?函数的参数传递分为哪2类呢,两者有什么区别呢?值传递和地址传递。值传递,形参声明中,使用普通变量作为形参,其本质是将实参的值复制(赋值)给形参如:void switch_num(int a, int b)。地址传递,形参声明中,使用指针变量作为形参其本质是将内存地址传递给函数,用指针(地址)完成函数体逻辑如:void switch_num_pointer(int *a, int *b)。
问题解答:
1. 函数体的五部分组成及其作用
一个完整的函数体由以下五部分组成:
-
函数返回类型:指定函数返回的数据类型。例如,
int
表示返回一个整数,void
表示函数不返回任何值。 -
函数名:用于标识函数的名称。在调用函数时,需要使用这个名称。比如
switch_num
和switch_num_pointer
。 -
参数列表:函数参数的定义,包括参数的数据类型和参数名。参数列表用于传递数据给函数,比如
int a, int b
或int *a, int *b
。 -
函数体(代码块):包含在花括号
{}
内的代码块,是函数的具体实现部分。函数体执行特定的操作。例如,switch_num
和switch_num_pointer
中的交换逻辑。 -
返回语句(可选):用于返回函数的结果。在
void
类型的函数中,返回语句是可选的,而在其他返回类型的函数中,必须使用return
来返回相应类型的值。
2. 函数的实参和形参
-
形参(形式参数):在函数定义中,函数名后面括号中的变量,如
int a
和int b
,以及int *a
和int *b
。形参用于接收调用函数时传递的实参。 -
实参(实际参数):在函数调用时,传递给函数的实际值或变量,如
switch_num(x, y)
中的x
和y
,以及switch_num_pointer(&x, &y)
中的&x
和&y
。
3. 函数的参数传递方式
函数参数传递分为两类:
-
值传递:
- 概念:函数调用时,将实参的值复制一份,传递给形参。形参的修改不会影响实参。
- 例子:
void switch_num(int a, int b)
中,a
和b
是普通变量,实参x
和y
的值被复制给形参a
和b
。在函数体内,交换了a
和b
的值,但由于是值传递,实参x
和y
不会受到影响,所以在函数调用结束后,x
和y
的值依然是原来的1和2。
-
地址传递:
- 概念:函数调用时,将实参的内存地址传递给形参,函数内通过指针操作直接影响实参的值。
- 例子:
void switch_num_pointer(int *a, int *b)
中,a
和b
是指针变量,实参&x
和&y
(即x
和y
的地址)被传递给形参a
和b
。在函数体内,交换了指针a
和b
所指向的值,即交换了x
和y
的值。由于是地址传递,实参x
和y
的值被直接修改,所以在函数调用结束后,x
和y
的值被交换。
4. 值传递与地址传递的区别
- 值传递:传递的是实参的值,形参与实参是独立的变量,形参的修改不会影响实参。
- 地址传递:传递的是实参的地址,形参是指向实参的指针,形参的修改直接影响实参。
在上面的代码中:
switch_num(x, y)
使用值传递,所以x
和y
的值在函数调用后没有变化。switch_num_pointer(&x, &y)
使用地址传递,所以x
和y
的值在函数调用后被交换了。