当前位置:首页 » 《关于电脑》 » 正文

[C语言] 函数实参与形参详解

0 人参与  2024年11月02日 11:21  分类 : 《关于电脑》  评论

点击全文阅读



文章目录

实参的概念示例:实参传递 形参的概念形参的语法结构示例:形参接收实参 实参与形参的关系实参与形参的传递过程示例:实参与形参的关系 实参和形参的传递方式值传递示例:值传递 指针传递示例:指针传递 示例讲解示例1:计算两数之和(值传递)示例2:交换两个数的值(指针传递)示例讲解 扩展内容:指针与参数传递传递数组示例:传递数组 解释 传递结构体指针示例:传递结构体指针 指针与实参传递的总结 总结
在C语言编程中, 函数是实现代码复用、简化逻辑和提高代码组织的重要工具。而函数的核心之一就是 参数传递机制,参数包括 实参(实际参数)和 形参(形式参数)。本文将详细讲解C语言中实参和形参的概念、它们的区别、关系以及使用方法,帮助你理解函数参数传递的原理和实际应用。我们还将探讨通过指针传递参数的方式,以便在函数中直接修改实参的值。


实参的概念

实参(实际参数)是在函数调用时传递给函数的值或表达式。它们是函数执行所需的具体数据。在调用函数时,实参被放置在函数名后面的括号内,实参可以是变量、常量,或者更复杂的表达式。

示例:实参传递

#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 函数从用户输入获取,之后作为实参传递给库函数 sqrtsqrt(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;}

在上述代码中:

变量 xy 是实参,函数 add 的形参是 ab。调用 add(x, y) 时,实参 xy 的值分别被复制到形参 ab,并在函数体内进行求和操作。

实参和形参的传递方式

在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


示例讲解

示例1:计算两数之和(值传递)

#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 接收两个参数 ab,并输出它们的和。实参 xy 的值被传递给形参 ab

示例2:交换两个数的值(指针传递)

#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 接受两个指针 ab,它们分别指向 xy 的地址。在 swap 函数内部,通过解引用 *a*b 来访问并修改 xy 的值。由于传递的是地址,swap 函数的操作会直接影响实参 xy 的值。因此,交换操作完成后,xy 的值已经改变。

程序的输出为:

交换前: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语言程序至关重要。特别是在处理数组、结构体等复杂数据结构时,使用指针传递可以提高程序的性能并优化内存使用。


点击全文阅读


本文链接:http://zhangshiyu.com/post/181364.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1