规则
任何语言,不管是C/C++/JAVA/C#,函数中传递参数或者返回值,都是按照值传递的,都是复制一份原来的变量里面的值。
参数如果是整型则拷贝的是整型里面的整型值,参数如果是指针则拷贝的是指针里面的内存地址
c语言中
返回值实际上存在一个复制
返回整型的时候,复制的是那个整型。
返回指针的时候,复制的是那个指针,但是指针指向的地址在函数的如果在栈上分配(即不是alloc在堆上分配内存),函数执行完后,那块内存已经无效了。
java语言中
返回值实际上存在一个复制
返回整型的时候,复制的是那个整型。
返回对象的时候,复制的是那个对象地址,但是对象指向的地址在方法堆中,方法执行完后,那块内存仍然有效,除非GC回收该堆上内存
- java方法中传递参数示例
public class Test {
public static void main(String args[]) {
int i = 1;
// 传递给add方法的参数i是复制那个整型值1
add(i);
// 输出1,不是2
System.out.println(i);
}
public static void add(int i) {
// 修改复本i的值,实际上外层i的值仍未改变
i++;
}
}
class A {
public int i = 1;
}
public class Test {
public static void main(String args[]) {
A a = new A();
// 传递给add方法的参数a是复制a的地址的复本
add(a);
// 输出1,不是2
System.out.println(a.i);
}
public static void add(A a) {
// 修改a地址指向new A()在堆中创建出来的内存首地址,实际上外层a地址仍未改变
a = new A();
a.i++;
}
}
- c语言函数中传递参数示例
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int i;
} A;
static void add(A a) {
// 修改a的i属性值不会修改上层a的值,因为方法参数传递的是a的拷贝复本
a.i = 100;
}
int main(void) {
A a;
a.i = 1;
add(a);
// 输出仍为1
printf("%d", a.i);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int i;
} A;
static void add(A* a) {
// 函数传递的是a的内存地址拷贝,修改该内存地址指向的属性有效
a->i = 100;
}
int main(void) {
A a;
a.i = 1;
add(&a);
// 输出为100
printf("%d", a.i);
return 0;
}
- java方法中返回参数示例
public class Test {
public static void main(String args[]) {
// 将create()里面返回的拷贝的值赋值给i
int i = create();
// 输出2
System.out.println(i);
}
public static int create() {
int i = 2;
// 返回i值的拷贝,即2
return i;
}
}
class A {
public int i = 0;
}
public class Test {
public static void main(String args[]) {
A a = create();
// 输出2
System.out.println(a.i);
}
public static A create() {
// 在堆中分配内存
A a = new A();
a.i = 2;
// 返回a对象指向的内存地址拷贝,内存地址是在堆中内存地址,返回出去不会被清除
return a;
}
}
- c语言函数中返回参数示例
#include <stdio.h>
#include <stdlib.h>
static int create() {
int i = 2;
// 返回i值的拷贝,即整型数值2
return i;
}
int main(void) {
// 将create()里面返回的拷贝的值赋值给i
int i = create();
// 输出2
printf("%d", i);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int i;
} A;
static A create() {
A a;
a.i = 100;
// 有问题,此时变量a内存分配在栈上,函数返回时栈上分配的空间会清空,虽然存储空间会缓存一段时间
return a;
}
int main(void) {
A a = create();
printf("%d", a.i);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int i;
} A;
static A* create() {
A* a;
// 在堆上分配内存
a = malloc(sizeof(A));
a->i = 100;
// 返回堆上分配的内存地址的拷贝,内存地址是在堆中内存地址,返回出去不会被清除,除非调用free函数清除堆上内存
return a;
}
int main(void) {
A* a = create();
printf("%d", a->i);
return 0;
}