函数实参与形参的区别

简介: 函数实参与形参的区别

一、C语言



程序清单1


#include <stdio.h>
void swap(int x, int y) {
  int tmp = x;
  x = y;
  y = tmp;  
}
int main() {
  int a = 3;
  int b = 5;
  printf("a = %d b = %d\n", a, b);
  swap(a, b);
  printf("a = %d b = %d\n", a, b);
  return 0;
}


输出结果:


ee394fb90da344b9bc11fc7be95c65a3.png


分析:


在程序清单1中,a, b 为实参,x, y 为形参。


当 a 和 b 传入 swap( ) 函数的时候,x 和 y 确实能拿到 3 和 5 这两个值,但 x 和 y 本身与 a 和 b拥有不同的地址,这就造成一个结果:在swap() 函数中,只交换了形参 x 和 y 的值,对于实参 a 和 b 来说,毫无影响。


4238684218a149fab1346a9bc3a3318d.png



程序清单2


#include <stdio.h>
void swap(int* pa, int* pb) {
  int tmp = *pa; // 解引用
  *pa = *pb;
  *pb = tmp;
}
int main() {
  int a = 3;
  int b = 5;
  printf("a = %d b = %d\n", a, b);
  swap(&a, &b);
  printf("a = %d b = %d\n", a, b);
  return 0;
}


输出结果:


b14261812cd9468e8416b1a1feeac44b.png


分析:


在程序清单2 中,当我们实参传的是 a 和 b 的地址时,情况就完全不一样了,在 swap( ) 函数中,我们形参拿整型指针类型来接收地址,最后再通过解引用符号 " * " 来拿到地址对应的值,即可交换。


这里需要注意: pa 和 pb 存的值是 a 和 b 的地址,然而 pa 和 pb 本身是一个指针变量,既然是变量,它们也有属于自己的地址,前者后者不能搞混了。


99924f74720f435f87e2302374137afc.png


二、Java



程序清单3


public class Test {
    public static void main(String[] args) {
        int a = 3;
        int b = 5;
        System.out.println("a = " + a + " b = " + b);
        swap(a,b);
        System.out.println("a = " + a + " b = " + b);
    }
    public static void swap(int a, int b){
        int temp = a;
        a = b;
        b = temp;
    }
}


输出结果:


a2d0b4c5e47046b495b723f8962584cf.png


在程序清单3中,现在我们就可以理解了 swap() 函数中的 a 和 b 和 main 函数中的 a 和 b 是不一样的。


程序清单4


public class Test {
    public static void main(String[] args) {
        int[] arr = {3, 5};
        System.out.println("a = " + arr[0] + " b = " + arr[1]);
        swap(arr);
        System.out.println("a = " + arr[0] + " b = " + arr[1]);
    }
    public static void swap(int[] arr) {
        int tmp = arr[0];
        arr[0] = arr[1];
        arr[1] = tmp;
    }
}


输出结果:


086aeeeafceb4b2d90a4e38edb190d2c.png


在 Java 中,我们拿不到局部变量的地址,或者说是拿不到栈区的地址。所以在程序清单4中,如果想要利用函数进行交换值,我们只能通过改变堆区的值来进行交换。


9f5e47b6c29a43a6850e8b5e508df974.png


三、总结



① 形参是实参的一份临时拷贝,其只在当前函数中有效,出了当前函数,即被销毁,所以改变形参本质上不会影响实参的状态。


② 在 C 语言中,我们可以利用指针接收地址,从而拿到地址对应的值来直接进行改变实参。


③ 在 Java 中,形参依然是实参的一份临时拷贝。但情况又有不同,因为栈区存放的局部变量对应的地址,我们无法获得,所以我们只能通过数组改变堆区上的某个值,这样一来,也可以完成交换的逻辑。而数组本身就是一个引用类型,这样一来,就是和地址有关联了。



目录
相关文章
|
4月前
|
存储 前端开发 JavaScript
前端基础(十一)_函数声明及调用、函数的形参与实参、arguments参数、函数的参数类型、函数中的问题
本文介绍了JavaScript中函数的声明及调用、形参与实参的概念、arguments对象的使用、函数参数的类型以及函数中this的作用。通过示例代码详细解释了函数如何接收参数、如何处理参数个数不匹配的情况,以及函数在不同上下文中this的指向。
39 1
|
7月前
|
开发框架 .NET 编译器
程序与技术分享:C#基础知识梳理系列三:C#类成员:常量、字段、属性
程序与技术分享:C#基础知识梳理系列三:C#类成员:常量、字段、属性
47 2
|
8月前
|
存储 C语言
C语言中向函数传递值和从函数返回值的技术解析
C语言中向函数传递值和从函数返回值的技术解析
89 0
|
编译器 Linux C++
学C的第三十天【自定义类型:结构体、枚举、联合】-1
1 . 结构体 (1). 结构体的基础知识: 结构是一些值的集合,这些值称为成员变量。 结构的每个成员可以是不同类型的变量。
|
存储
学C的第三十天【自定义类型:结构体、枚举、联合】-2
(7). 修改默认对齐数: 结构在对齐方式不合适的时候,我们可以自己更改默认对齐数。 使用 #pragma 预处理指令,修改默认对齐数
|
8月前
|
C语言
【C语言】函数实参与形参详解
【C语言】函数实参与形参详解
368 0
|
编译器 C语言 C++
一分钟搞懂什么是this指针(未涉及静态成员和函数)
一分钟搞懂什么是this指针(未涉及静态成员和函数)
|
存储 算法 编译器
【C++技能树】令常规运算符用在类上 --类的六个成员函数II
C++中为了增强代码的可读性,加入了运算符的重载,与其他函数重载一样
63 0