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 的地址,使得函数能够直接修改原始变量的值。

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


总结

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


相关文章
|
2月前
|
程序员 C语言 开发者
pymalloc 和系统的 malloc 有什么区别
pymalloc 和系统的 malloc 有什么区别
|
2月前
|
程序员 C语言 开发者
pymalloc 和系统的 malloc 有什么区别?
pymalloc 和系统的 malloc 有什么区别?
|
3月前
|
存储 C语言
C语言中a 和&a 有什么区别
在C语言中,&quot;a&quot; 是一个变量的名字,代表存储在内存中的某个值。而&quot;&a&quot; 则是获取该变量的内存地址,即变量a在计算机内存中的具体位置。这两者的主要区别在于:&quot;a&quot; 操作的是变量中的值,&quot;&a&quot; 操作的是变量的内存地址。
379 23
|
3月前
|
存储 C语言
C语言:普通局部变量、普通全局变量、静态局部变量、静态全局变量的区别
C语言中,普通局部变量在函数内部定义,作用域仅限于该函数;普通全局变量在所有函数外部定义,作用域为整个文件;静态局部变量在函数内部定义但生命周期为整个程序运行期;静态全局变量在所有函数外部定义,但仅在定义它的文件内可见。
167 10
|
3月前
|
程序员 编译器 C语言
C中的 malloc 和C++中的 new 有什么区别
在C语言中,`malloc`函数用于在运行时分配内存,返回指向所分配内存的指针,需显式包含头文件 `&lt;stdlib.h&gt;`。而在C++中,`new`不仅分配内存,还对其进行构造初始化,且直接使用类型声明即可,无需额外包含头文件。`new`还支持数组初始化,能更好地融入C++的面向对象特性,而`malloc`仅作为内存分配工具。使用完毕后,`free`和`delete`分别用于释放`malloc`和`new`分配的内存。
73 21
|
3月前
|
存储 C语言
C语言:结构体与共用体的区别
C语言中,结构体(struct)和共用体(union)都用于组合不同类型的数据,但使用方式不同。结构体为每个成员分配独立的内存空间,而共用体的所有成员共享同一段内存,节省空间但需谨慎使用。
|
3月前
|
存储 编译器 C语言
C语言函数的定义与函数的声明的区别
C语言中,函数的定义包含函数的实现,即具体执行的代码块;而函数的声明仅描述函数的名称、返回类型和参数列表,用于告知编译器函数的存在,但不包含实现细节。声明通常放在头文件中,定义则在源文件中。
|
3月前
|
存储 C语言
C语言指针与指针变量的区别指针
指针是C语言中的重要概念,用于存储内存地址。指针变量是一种特殊的变量,用于存放其他变量的内存地址,通过指针可以间接访问和修改该变量的值。指针与指针变量的主要区别在于:指针是一个泛指的概念,而指针变量是具体的实现形式。
|
3月前
|
存储 编译器 C语言
C语言:数组名作为类型、作为地址、对数组名取地址的区别
在C语言中,数组名可以作为类型、地址和取地址使用。数组名本身代表数组的首地址,作为地址时可以直接使用;作为类型时,用于声明指针或函数参数;取地址时,使用取地址符 (&),得到的是整个数组的地址,类型为指向该类型的指针。
|
3月前
|
C语言 C++
C 语言的关键字 static 和 C++ 的关键字 static 有什么区别
在C语言中,`static`关键字主要用于变量声明,使得该变量的作用域被限制在其被声明的函数内部,且在整个程序运行期间保留其值。而在C++中,除了继承了C的特性外,`static`还可以用于类成员,使该成员被所有类实例共享,同时在类外进行初始化。这使得C++中的`static`具有更广泛的应用场景,不仅限于控制变量的作用域和生存期。
72 10