实参(实际参数)是在函数调用时传递给函数的值或表达式。它们是函数执行所需的具体数据。在调用函数时,实参被放置在函数名后面的括号内,实参可以是变量、常量,或者更复杂的表达式。
#include <stdio.h>
#include <math.h>
int main(void) {
int a;
scanf("%d", &a); // 从用户获取输入作为实参
printf("平方根是: %.2f\n", sqrt(a)); // 传递实参a给sqrt函数
return 0;
}在上述示例中,a 是一个整数变量,它的值通过 scanf 函数从用户输入获取,之后作为实参传递给库函数 sqrt。sqrt(a) 的括号内的 a 就是实参,函数会使用这个实参进行计算。
实参的特点包括:
形参(形式参数)是在函数定义时声明的参数,它用于接收函数调用时传递的实际参数值。形参在函数定义时声明,并在函数体内作为局部变量使用,作用范围仅限于函数内部。
返回类型 函数名(形参列表) {
// 函数体
}形参列表由多个形参组成,每个形参包括数据类型和参数名。形参在函数定义时不会有实际值,只有在函数调用时,实参的值才会传递给形参。
#include <stdio.h>
void print_square_root(double num) {
printf("平方根是: %.2f\n", sqrt(num)); // num 是形参
}
int main() {
double x = 16.0;
print_square_root(x); // 实参x传递给形参num
return 0;
}在这个例子中,print_square_root 函数有一个形参 num,在 main 函数调用 print_square_root 时,实参 x 被传递给形参 num,然后 num 在函数体中被用于计算平方根。
形参的特点包括:
实参和形参之间的关系可以理解为实参为形参提供值,并且这种值传递是在函数调用时发生的。当函数被调用时,实参的值被传递给形参,形参用于函数内部的计算。
#include <stdio.h>
void add(int a, int b) {
int sum = a + b;
printf("两数之和是: %d\n", sum);
}
int main() {
int x = 5;
int y = 3;
add(x, y); // 实参 x 和 y 传递给函数 add 的形参 a 和 b
return 0;
}在上述代码中:
x 和 y 是实参,函数 add 的形参是 a 和 b。add(x, y) 时,实参 x 和 y 的值分别被复制到形参 a 和 b,并在函数体内进行求和操作。在C语言中,函数的参数传递主要有两种方式:
值传递是C语言中最常见的参数传递方式。通过值传递,函数内部修改形参的值并不会影响原始的实参,因为函数内部处理的是实参的副本。
#include <stdio.h>
void increment(int a) {
a = a + 1; // 修改的是形参 a 的值
}
int main() {
int x = 10;
increment(x); // 传递实参 x 的值
printf("x 的值是: %d\n", x); // 输出仍然是 10
return 0;
}在这个例子中,虽然在 increment 函数中修改了形参 a 的值,但实参 x 并没有受到影响,仍然保持原始值 10。这是因为 x 的值是通过值传递的方式传递给 a,函数内部的修改只影响 a,不会修改 x。
如果希望在函数内部修改实参的值,可以通过指针传递。通过传递实参的地址,函数内部可以通过形参直接访问并修改实参的值。
#include <stdio.h>
void increment(int *a) {
*a = *a + 1; // 修改的是实参的值
}
int main() {
int x = 10;
increment(&x); // 传递实参 x 的地址
printf("x 的值是: %d\n", x); // 输出是 11
return 0;
}在这个例子中,increment 函数接受一个指针 a,并通过解引用 *a 修改实参的值。由于传递的是 x 的地址,函数内部的修改会直接作用于实参 x,因此 x 的值变为 11。
#include <stdio.h>
void sum(int a, int b) {
int result = a + b;
printf("两数之和是: %d\n", result);
}
int main() {
int x = 5, y = 10;
sum(x, y); // 传递值
return 0;
}在这个例子中,函数 sum 接收两个参数 a 和 b,并输出它们的和。实参 x 和 y 的值被传递给形参 a 和 b。
#include <stdio.h>
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
int main() {
int x = 5, y = 10;
printf("交换前:x = %d, y = %d\n", x, y);
swap(&x, &y); // 传递x和y的地址
printf("交换后:x = %d, y = %d\n", x, y);
return 0;
}在上述示例中,swap 函数的目的是交换两个整数的值。我们通过指针传递实现了这一目标:
swap 接受两个指针 a 和 b,它们分别指向 x 和 y 的地址。swap 函数内部,通过解引用 *a 和 *b 来访问并修改 x 和 y 的值。swap 函数的操作会直接影响实参 x 和 y 的值。因此,交换操作完成后,x 和 y 的值已经改变。程序的输出为:
交换前:x = 5, y = 10
交换后:x = 10, y = 5这种通过指针传递的方式,允许函数修改调用者传递的实际数据,从而实现更灵活的操作。
C语言中,指针是处理内存地址的关键工具。使用指针传递参数不仅可以让函数修改实参的值,还可以在函数内部操作复杂的数据结构,如数组、结构体等。
在C语言中,数组作为函数参数时会自动退化为指针。因此,传递数组实质上是传递数组的首地址,函数内部可以访问和修改数组的元素。
#include <stdio.h>
void double_array(int *arr, int size) {
for (int i = 0; i < size; i++) {
arr[i] *= 2;
}
}
int main() {
int numbers[] = {1, 2, 3, 4, 5};
int size = sizeof(numbers) / sizeof(numbers[0]);
double_array(numbers, size); // 传递数组的首地址
printf("数组元素加倍后的结果:");
for (int i = 0; i < size; i++) {
printf("%d ", numbers[i]);
}
printf("\n");
return 0;
}在该示例中:
double_array 通过指针访问数组,并将每个元素的值加倍。numbers 数组。输出结果为:
数组元素加倍后的结果:2 4 6 8 10对于复杂数据结构如结构体,使用指针传递可以避免复制整个结构体数据,提高效率。
#include <stdio.h>
struct Point {
int x;
int y;
};
void move_point(struct Point *p, int dx, int dy) {
p->x += dx;
p->y += dy;
}
int main() {
struct Point p1 = {10, 20};
printf("移动前:x = %d, y = %d\n", p1.x, p1.y);
move_point(&p1, 5, -3); // 传递结构体指针
printf("移动后:x = %d, y = %d\n", p1.x, p1.y);
return 0;
}在这个示例中,move_point 函数通过指针操作 Point 结构体,移动点的坐标。通过传递结构体的指针,我们可以直接修改结构体的内容。
程序的输出为:
移动前:x = 10, y = 20
移动后:x = 15, y = 17通过指针传递的方式,函数可以修改实参的值,或者操作复杂的数据结构。与值传递相比,指针传递效率更高,特别是在处理大型数据时,避免了不必要的内存复制。
在C语言中,实参和形参是函数定义和调用时的核心概念。实参是实际传递给函数的值,形参则是在函数中接收实参的局部变量。实参和形参之间通过值传递或指针传递实现数据的传递。
理解实参和形参的关系、以及它们的传递方式对于编写高效的C语言程序至关重要。特别是在处理数组、结构体等复杂数据结构时,使用指针传递可以提高程序的性能并优化内存使用。