Skip to main content

传参

David LiuAbout 3 min

传参

传参设计

局部变量传递

父传子

  • 非引用类型需要函数传参(BFS节点),如深度信息可以直接父传子depth + 1
  • 引用类型变量需要结合回溯来实现。

子传父

  • DFS通过返回值将子问题结果传递给父问题。

全局变量传递

邻接:回溯的思想,对复杂的变量需要使用forward()和backward(),可以节省内存空间

访问:序号、前后序时间戳、访问前驱、访问后继,需要全局参数传递,因为不再是父子相传

数据类型

在 Java 中类型可分为两大类:值类型与引用类型。

  1. 值类型就是基本数据类型(如 int、double 等)
  2. 引用类型是指除了基本的变量类型之外的所有类型

所有的类型在内存中都会分配一定的存储空间(形参在使用的时候也会分配存储空间,方法调用完成之后,这块存储空间自动消失)

基本的变量类型只有一块存储空间(分配在stack中),而引用类型有两块存储空间(一块在 stack 中,一块在 heap 中)。

值类型

即八大基本数据类型,包含四类:

  1. 整数类型

    byte, short, int, long

  2. 浮点类型

    float, double

  3. 布尔类型

    boolean

  4. 字符类型

    char

引用类型

即复合数据类型,除了基本的变量类型之外的所有类型,包括如下三类

  1. 类类型

    class

  2. 接口类型

    interface

  3. 数组

    []

传参类型

值传递、引用传递

指针传递(C类特有)

值传递

文件复制

Java的八大基本数据类型都是值传递(本质上都是值传递,因为引用类型传递的也是对象引用的值)

C++中默认值传递

Python中没有值传递,Python的不可变类型可以认为是值传递的(其实本质上还是引用传递)

你用字符串来做实验,并推广为所有Java对象的做法,并不是特别合适。Java的String类型有特殊的处理:所有编译期认识的字符串,都会被放到常量池,于是下面的语句:

a = "s";
b = "s";

a和b并不像其它对象一样有创建的动作,都是直接指向常量池中的"s",所以你可以得到a==b。而下面的语句:

a = new String("s");
b = new String("s");

是分别在Java堆中创建了2个对象,此时a!=b。

本质上说,对于基本数据类型(整数、字符等),Java的符号==,用于判断二者的值是否相等;对于对象类型,Java的符号==,用于判断两个变量是否是“同一个对象”,equals()方法才是用于判断两个对象是否相等。

引用传递

可以理解为别名、代号、文件的快捷方式

Java除了基本数据类型以外的其他数据本质上都是引用传递(及各种对象)

C++中在参数列表中加地址符&修饰

Python中全是引用传递

数组的引用传递

修改实例和修改引用

".", "[]"修改的是实例

否则修改的是引用

堆空间、

  • 存放new得到的对象
  • 无限制(剩余内存的大小)

栈空间

  • 存放对象的引用
  • 值类型变量
  • C++函数中的数组(C++危险的地方)
  • 有限制,一般很小,MB量级
  • 函数调用栈

函数调用栈

每调用一个函数就放入到筒里,

递归需谨慎

递归调用容易爆栈、人为调用栈不会爆栈

除非在c/c++的函数中定义大数组 -- 危险行为

递归三要素

递归的定义

递归的拆解

递归的出口