首页 > 编程笔记 > C语言笔记

C语言实参和形参是什么?怎么用?(附带示例)

在C语言中,实参和形参是函数调用过程中非常重要的概念,理解它们之间的关系和使用方法,对于掌握函数的工作原理至关重要。
 

形参(形式参数)是在函数定义时声明的参数,它们在函数内部充当占位符的角色,用于接收调用函数时传递的值。形参只在函数内部有效,函数执行结束后就会被销毁。
 

实参(实际参数)是在调用函数时实际传递给函数的值,这些值会被复制到对应的形参中,然后在函数内部使用。实参可以是常量、变量、表达式或者函数调用的结果。


让我们通过一个简单的例子来说明实参和形参的概念:

#include <stdio.h>

// 函数声明,x 和 y 是形参
int add(int x, int y) {
    return x + y;
}

int main() {
    int a = 5, b = 3;
    int result;

    // 函数调用,a 和 b 是实参
    result = add(a, b);

    printf("The sum of %d and %d is %d\n", a, b, result);

    return 0;
}

在这个例子中,add 函数定义了两个形参 x 和 y。当我们在 main 函数中调用 add(a, b) 时,变量 a 和 b 就是实参。函数调用时,a 的值被复制给 x,b 的值被复制给 y。
 

实参和形参之间的数据传递有几种不同的方式,主要包括值传递和引用传递(在C语言中通过指针实现)。

1. 值传递(Pass by Value)

在值传递中,实参的值被复制到形参中,这意味着在函数内部对形参的修改不会影响到实参。C语言中的基本数据类型(如 int、float、char 等)默认使用值传递。

#include <stdio.h>

void swap(int x, int y) {
    int temp = x;
    x = y;
    y = temp;
    printf("Inside swap function: x = %d, y = %d\n", x, y);
}

int main() {
    int a = 10, b = 20;
    printf("Before swap: a = %d, b = %d\n", a, b);
    swap(a, b);
    printf("After swap: a = %d, b = %d\n", a, b);
    return 0;
}

输出结果:

Before swap: a = 10, b = 20
Inside swap function: x = 20, y = 10
After swap: a = 10, b = 20

在这个例子中,尽管 swap 函数内部交换了 x 和 y 的值,但 main 函数中的 a 和 b 并没有被交换,因为 x 和 y 只是 a 和 b 的副本。

2. 引用传递(Pass by Reference)

C语言中没有直接的引用传递机制,但我们可以通过传递指针来实现类似的效果,这种方式允许函数修改调用者的变量。

#include <stdio.h>

void swap(int *x, int *y) {
    int temp = *x;
    *x = *y;
    *y = temp;
    printf("Inside swap function: *x = %d, *y = %d\n", *x, *y);
}

int main() {
    int a = 10, b = 20;
    printf("Before swap: a = %d, b = %d\n", a, b);
    swap(&a, &b);
    printf("After swap: a = %d, b = %d\n", a, b);
    return 0;
}

输出结果:

Before swap: a = 10, b = 20
Inside swap function: *x = 20, *y = 10
After swap: a = 20, b = 10

在这个修改后的版本中,我们传递了 a 和 b 的地址给 swap 函数,函数通过解引用操作符*来访问和修改这些地址所指向的值,从而实现了真正的交换。


了解实参和形参的概念,以及它们的传递方式对于编写高效、正确的 C 程序至关重要,在设计函数时,我们需要根据具体需求来选择合适的参数传递方式。如果函数不需要修改传入的参数,使用值传递就足够了;如果需要在函数内部修改传入的参数并反映到调用者,那么就应该考虑使用指针来实现引用传递。
 

此外,C语言还支持数组作为函数参数。当传递数组时,实际上传递的是数组的首地址,这使得函数可以直接修改原数组的内容。例如:

#include <stdio.h>

void modifyArray(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]);

    printf("Before modification:\n");
    for (int i = 0; i < size; i++) {
        printf("%d ", numbers[i]);
    }
    printf("\n");

    modifyArray(numbers, size);

    printf("After modification:\n");
    for (int i = 0; i < size; i++) {
        printf("%d ", numbers[i]);
    }
    printf("\n");

    return 0;
}

输出结果:

Before modification:
1 2 3 4 5
After modification:
2 4 6 8 10

在这个例子中,modifyArray 函数接收一个整型数组和它的大小作为参数。由于数组名本质上是一个指向数组第一个元素的指针,所以函数可以直接修改原数组的内容。


总的来说,理解实参和形参的概念,以及不同的参数传递方式,可以帮助我们更好地设计和实现函数。

相关文章