黑马程序员技术交流社区
标题:
一个内存的小问题
[打印本页]
作者:
彭嘉聪
时间:
2012-1-28 14:21
标题:
一个内存的小问题
java代码
class testing
{
public static void main(String[] args)
{
int b = 4;
add(b);
System.out.println(b);
}
public static void add(int b){
b = b+3;
}
}
复制代码
输出为4
C代码
#include<stdio.h>
void add(int * x);
int main(void){
int b = 4;
add(&b);
printf("%d",b);
return 0;
}
void add(int * x){
*x = *x+3;
}
复制代码
输出为7
问题如下:
如果改变java中主函数的b值?
众所周知C语言要利用函数改变主函数的值需要用到指针,但是貌似java没有类似操作
但是在java中传进数组,类这些却可以改变实际变量的值,令我想了一下,发现java (new)出来的类和数组
就类似于c/c++语言中malloc动态分配出来的空间那样,可以长期保留,并且由指针变量所引导,要调用的时候只要知道其指针变量就可以自由的操纵数据。所以当java传进这些参数的时候,就自动附其地址进去,而不是栈变量的直接传值。
不知道有没有同学有其他见解,一起讨论
作者:
黄秋
时间:
2012-1-28 15:54
本帖最后由 黄秋 于 2012-1-28 15:58 编辑
因为JAVA的jvm里面有两个存储区,一个是暂存区(是一个堆栈),另一个是变量区。 b = b+3 是先将b的值4 存入暂存区,然后对变量区中的b 加3,这时b在变量区的值确实是7,但是暂存区的是4; 随后将暂存区(堆栈)的值4--- 弹出赋给变量区的b,所以最后b = 4 。想深入的,可再找些资料看看;若不,记住这种情况--- JAVA是不加1的,就行了。详细参看以前我与大家的讨论:
一样的代码,不一样的结果
作者:
最初的理想
时间:
2012-1-29 13:11
可不可以这样理解,基本数据类型传的是值而不是地址,当调用add(b)的时候执行add方法会在内存中开辟一个栈来执行这个add方法,将b作为形参传递给add时候,在add方法开辟的堆栈中就有一个临时变量的值是4,经过运算它的值又变为7,但是方法没有返回,方法运算结束,add方法开辟的栈空间就销毁了当然值为7的哪个临时变量也就销毁了,System.out.println(b);这句实际上是输出原来的b值,当然还是4.终归还是函数参数中传值和传地址的问题吧。当然如果牵涉到c中的指针的话,可能十有八九都和地址有关吧。
作者:
彭嘉聪
时间:
2012-1-29 14:27
最初的理想 发表于 2012-1-29 13:11
可不可以这样理解,基本数据类型传的是值而不是地址,当调用add(b)的时候执行add方法会在内存中开辟一个栈 ...
其实有个想法,就是变量传递的是值,是java已经固定化的,无法操纵变量的地址,不知这想法是否充分。而new出来的,就是类似c语言中malloc出来的,长久存在于内存的空间,无论是java new出来的数组还是String,一般C就是利用free来释放malloc出来的内存,而java却不需要,所以所谓的垃圾回收机制,就是查询没有引用到的对象然后进行free释放。
作者:
李杨
时间:
2012-1-31 03:56
C语言形式是叫做函数调用,形参是指针类型,传递的是指针变量的地址,经过运算后的值重新付给指针变量当然在其他函数中进行调用。这就是面向过程时的思想,采用地址来直接数据的交互。
Java中是pass by value 是值传递而不是传递地址。地址和引用不用,地址是确定而引用可以有很多个。Java面向对象主要体现的就是面向对象,而C体现的是面向过程,是针对地址进行交互的,涉及到硬件方面编程很多,比如单片机等。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2