黑马程序员技术交流社区

标题: 一个内存的小问题 [打印本页]

作者: 彭嘉聪    时间: 2012-1-28 14:21
标题: 一个内存的小问题
java代码
  1. class  testing
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 int b = 4;
  6.                 add(b);
  7.                 System.out.println(b);
  8.         }

  9.         public  static  void add(int b){
  10.                 b = b+3;
  11.         }
  12. }
复制代码
输出为4


C代码
  1. #include<stdio.h>

  2. void add(int * x);


  3. int main(void){

  4. int b = 4;
  5. add(&b);
  6. printf("%d",b);

  7. return 0;
  8. }


  9. void add(int * x){
  10.         *x = *x+3;
  11. }
复制代码
输出为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