C语言进阶教程(传值调用和传址调用的区别)

简介: C语言进阶教程(传值调用和传址调用的区别)

前言

本篇文章开始我将带大家深入的学习C语言中指针的使用方法,讲解一些容易出错的地方。


一、传值调用和传址调用

当我们使用传值调用(Pass by Value)方式在 C 语言中传递参数时,函数接收的是实际参数的值的副本。任何对形式参数的修改都不会影响到原始的实际参数。让我们通过一个示例来说明传值调用的工作原理:

#include <stdio.h>
void modifyValue(int num) {
    num = 10;  // 修改形式参数
    printf("Inside modifyValue: num = %d\n", num);
}
int main() {
    int number = 5;
    printf("Before calling modifyValue: number = %d\n", number);
    modifyValue(number);  // 传值调用
    printf("After calling modifyValue: number = %d\n", number);
    return 0;
}

输出结果为:

Before calling modifyValue: number = 5
Inside modifyValue: num = 10
After calling modifyValue: number = 5

在上述示例中,我们定义了 modifyValue() 函数,它接收一个形式参数 num,并将其修改为 10。然后,在 main() 函数中我们声明了一个名为 number 的变量并初始化为 5。然后,我们调用 modifyValue(number) 来传递 number 的值。

在函数调用期间,实际参数 number 的值被复制到 num 这个形式参数中。在 modifyValue() 函数内部,我们修改了 num 的值为 10。但是这个修改只影响了形式参数 num 的值,而没有影响到实际参数 number 的值。因此,在 main() 函数中输出 number 的值仍然是 5。

这就是传值调用的特性,函数对形式参数的修改不会传播到实际参数,而是只影响形式参数本身。

在 C 语言中,传递参数的地址以实现传址调用(Pass by Reference)。通过传址调用,函数可以直接访问和修改实际参数所在内存地址上的值。我将给出一个例子以说明传址调用的概念和用法:

#include <stdio.h>
void modifyValue(int* ptr) {
    *ptr = 10;  // 通过指针修改实际参数的值
}
int main() {
    int number = 5;
    printf("Before calling modifyValue: number = %d\n", number);
    modifyValue(&amp;number);  // 传址调用,将 number 的地址传递给函数
    printf("After calling modifyValue: number = %d\n", number);
    return 0;
}

输出结果为:

Before calling modifyValue: number = 5
After calling modifyValue: number = 10

在上面的示例中,我们定义了 modifyValue() 函数,它接收一个指针类型的形式参数 ptr。在函数内部,我们通过间接引用(使用 * 操作符)修改了实际参数 number 所在内存地址上的值。在 main() 函数中,我们声明了一个名为 number 的变量并初始化为 5。然后,通过 &number 将 number 的地址传递给 modifyValue() 函数,实现了传址调用。

由于函数直接引用了实际参数的内存地址,所以对形式参数 ptr 的修改会直接影响到实际参数 number 的值。因此,在 main() 函数中输出 number 的值为 10。

这就是传址调用的特性,函数可以直接操作实际参数的值,因为函数接收的是实际参数的地址(引用),以便可以修改实际参数本身,而不仅仅是形式参数的副本。


二、工程示例

当涉及到使用传值调用和传址调用的实际工程例子时,以下是两个常见的案例:

传值调用的实际工程例子:

在许多函数中,我们需要对参数进行计算并返回结果,而不希望修改原始的输入参数。这时传值调用是一种常见的选择。例如,考虑一个计算两个整数的和的函数:

   int add(int a, int b) {
       return a + b;
   }
   int main() {
       int x = 2;
       int y = 3;
       int sum = add(x, y);
       printf("Sum: %d\n", sum);
       return 0;
   }

在这个例子中,add 函数使用传值调用来接受整数 a 和 b 的副本。原始变量 x 和 y 的值不会被修改。函数返回 a + b 的结果,将其赋值给 sum 变量,并在 main 函数中进行打印。

传址调用的实际工程例子:

传址调用通常用于需要在函数内部修改原始参数值的情况。一个常见的实例是交换两个变量的值:

   void swap(int* a, int* b) {
       int temp = *a;
       *a = *b;
       *b = temp;
   }
   int main() {
       int x = 2;
       int y = 3;
       printf("Before swap: x = %d, y = %d\n", x, y);
       swap(&amp;x, &amp;y);
       printf("After swap: x = %d, y = %d\n", x, y);
       return 0;
   }

在这个例子中,swap 函数接受两个整数指针 a 和 b。通过解引用指针,函数内部交换了 a 和 b 的值。在 main 函数中,我们传递了 x 和 y 的地址,使得函数能够直接修改原始变量的值。

在实际工程中,根据具体的需求和设计,选择适当的参数传递方式非常重要。传值调用适用于不需要修改原始参数的情况,而传址调用适用于需要修改原始参数的情况。


总结

本篇文章就讲解到这里,希望大家理解什么是传值调用什么是传址调用。


相关文章
|
1天前
|
存储 开发框架 编译器
C语言进阶—自定义类型:结构体,枚举,联合
C语言进阶—自定义类型:结构体,枚举,联合
|
1天前
|
存储 C语言 C++
C语言进阶——指针
C语言进阶——指针
|
2天前
|
C语言
【用C语言轻松实现】- 扫雷【超详细教程】
【用C语言轻松实现】- 扫雷【超详细教程】
|
2天前
|
C语言
【用C语言轻松搞定】三子棋(超详细教程)
【用C语言轻松搞定】三子棋(超详细教程)
|
2天前
|
C语言
C语言程序设计——if与else if的区别及用法
C语言程序设计——if与else if的区别及用法
|
3天前
|
C语言
C语言进阶21收尾(编程练习)(atoi,strncpy,strncat,offsetof模拟实现+找单身狗+宏交换二进制奇偶位)(下)
C语言进阶21收尾(编程练习)(atoi,strncpy,strncat,offsetof模拟实现+找单身狗+宏交换二进制奇偶位)
8 0
|
3天前
|
C语言
C语言进阶21收尾(编程练习)(atoi,strncpy,strncat,offsetof模拟实现+找单身狗+宏交换二进制奇偶位)(上)
C语言进阶21收尾(编程练习)(atoi,strncpy,strncat,offsetof模拟实现+找单身狗+宏交换二进制奇偶位)
12 0
|
3天前
|
自然语言处理 编译器 Linux
C语言进阶⑳(程序环境和预处理)(#define定义宏+编译+文件包含)(下)
C语言进阶⑳(程序环境和预处理)(#define定义宏+编译+文件包含)
6 0
|
3天前
|
程序员 编译器 C语言
C语言进阶⑳(程序环境和预处理)(#define定义宏+编译+文件包含)(中)
C语言进阶⑳(程序环境和预处理)(#define定义宏+编译+文件包含)
13 0