目录
一、形参和实参
在函数使用过程中,参数可以分为实际参数(实参)和形式参数(形参)两种类型。让我们通过以下代码示例来理解这两个概念:
#include <stdio.h>
int Add(int x, int y) // x和y是形式参数(形参)
{
int z = 0;
z = x + y;
return z;
}
int main()
{
int a = 0;
int b = 0;
// 输入
scanf("%d %d", &a, &b);
// 调用加法函数,完成a和b的相加
// 求和的结果放在r中
int r = Add(a, b); // a和b是实际参数(实参)
// 输出
printf("%d\n", r);
return 0;
}
1、实参(Actual Parameter)
在上述代码中,第17行调用Add
函数时传递给函数的参数a
和b
称为实际参数,简称实参。
实参是函数调用时实际传递给函数的值
实参可以是常量、变量或表达式
实参在函数调用前就已经被分配了内存空间
实参的值在函数调用时被传递给形参
2、形参(Formal Parameter)
在代码第2行定义函数时,函数名Add
后括号中的x
和y
称为形式参数,简称形参。
形参是函数定义时声明的参数,用于接收实参传递的值
形参只有在函数被调用时才会分配内存空间
函数调用结束后,形参所占用的内存空间会被释放
形参的作用域仅限于函数内部
3、形参与实参的关系
#include <stdio.h>
int Add(int x, int y) // x和y的地址与a和b不同
{
int z = 0;
z = x + y;
return z;
}
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a, &b);
int r = Add(a, b);
printf("%d\n", r);
return 0;
}
虽然实参将值传递给形参,但它们之间存在以下重要关系:
独立的内存空间:形参和实参各自拥有独立的内存空间
单向值传递:在C语言中,参数传递是值传递,即实参的值会被复制给形参
临时拷贝:形参实际上是实参的一份临时拷贝
地址不同:通过调试可以观察到,形参和实参的地址是不同的
二、return语句详解
在函数设计中,return
语句用于从函数返回一个值或终止函数的执行。以下是关于return
语句的重要注意事项:
返回值类型:
可以返回一个数值:
return 5;
可以返回一个表达式:
return x + y;
(先计算表达式,再返回结果)
无返回值:
对于返回类型为
void
的函数,可以直接写return;
如果
void
函数没有return
语句,函数会在执行完最后一条语句后自动返回
执行特性:
return
语句执行后,函数立即终止,后续代码不会执行一个函数可以有多个
return
语句,但只会执行其中一个
类型转换:如果返回值类型与函数声明类型不一致,系统会自动进行隐式类型转换为函数声明的类型
分支语句中的return:
如果函数中有分支语句(如
if
),必须确保所有路径都有返回值否则可能导致编译错误或未定义行为
默认返回类型:
如果函数没有声明返回类型,编译器会默认返回类型为
int
但现代C标准不建议省略返回类型
未使用return:如果函数声明了返回类型但没有使用
return
返回值,函数的返回值是未定义的
三、数组作为函数参数
在函数中使用数组作为参数时,需要注意以下特性:
1、基本用法示例
#include <stdio.h>
int main()
{
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int sz = sizeof(arr) / sizeof(arr[0]);
set_arr(arr, sz); // 设置数组内容为-1
print_arr(arr, sz); // 打印数组内容
return 0;
}
2、数组参数的重要特性(重点!!!)
参数匹配:
函数的形式参数必须与实参个数匹配
数组作为参数时,通常需要同时传递数组长度
数组形参的写法:
形参可以写成数组形式:
int arr[]
也可以写成指针形式:
int *arr
数组大小:
一维数组形参可以省略大小:
int arr[]
二维数组形参可以省略行数,但必须指定列数:
int arr[][5]
内存共享:
数组传参时,形参不会创建新的数组
形参操作的数组和实参数组是同一个数组(传递的是数组首地址)
在函数内修改数组元素会影响原始数组
3、实现示例
// 将数组所有元素设置为-1
void set_arr(int arr[], int sz)
{
int i = 0;
for(i = 0; i < sz; i++)
{
arr[i] = -1; // 修改会影响原始数组
}
}
// 打印数组内容
void print_arr(int arr[], int sz)
{
int i = 0;
for(i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
4、注意事项
数组名作为参数传递时,实际上传递的是数组首元素的地址
在函数内部无法通过
sizeof
获取数组总大小,因此通常需要额外传递数组长度对数组参数的修改会直接影响原始数组,因为操作的是同一块内存空间
为防止意外修改,可以使用
const
限定符:void print_arr(const int arr[], int sz)