1 int i=42; 2 int *p; 3 int *&r=p;//指向指针p的引用,就是给指针p取别名r,前面的*号表示引用的是一个指针。 4 5 r=&i; //实际上r就是指针p,对r的操作实际上就是对p的操作,让指针p指向i 6 *r=100;//通过对r进行解引用,实际上修改的是p,对指针p进行解引用,修改的是p所指向的值i
一般来说,为函数传入一个参数,如果希望函数执行完成后对参数的改动依然保留,那么有两种方式:
① 传入一个引用
② 传入一个指针
传入引用的方式很好理解,就是相当于将变量本身传入,针对变量所进行的一切修改都是直接对变量本身的修改。
传入指针则不然,传入指针后进行的修改,实际上是对指针指向的地址的内容进行修改,而不是对指针本身进行修改。比如说,指针的值是0x01cd3e2c,那么被修改的是0x01cd3e2c地址所代表的内容,指针的值0x01cd3e2c本身是不会被修改的。也就是说,传入指针,修改的是指向的内容,但指向的地址是不会变的。
即便对指针的值进行了修改,函数结束后,会发现指针的值依然不变,这是由于传入的参数不是引用造成的。传入的参数不是引用,那么对该参数进行的任何修改都不会保留到函数结束后。
比如:
void Function(int* pValue) { pValue = newint[10]; } void main() { int*pValue = NULL; Function(pValue); //1 }
上面的1执行完成后,会发现pValue的值依然是NULL。但是在函数体内刚对pValue进行修改时,其值却是正确的。
这是因为在函数体内,直接对pValue的值进行了修改,而非对pValue所指向的内存地址数据。pValue作为一个实参,传入后的一切修改都不会影响到自身的值,所以才会出现上述情况。
因此,改为如下代码:
void Function(int*& pValue) { pValue = newint[10]; } void main() { int*pValue = NULL; Function(pValue); //2 }
这样,将Function的传入参数改为指针的引用,于是对指针自身值的一切修改就都会得到保存。2执行完成后,会发现pValue的值是正确的。
指向指针的指针,也就是类似于void**。同理,void**作参数是相同的原因。
总之,如果要在函数内部修改指针自身的值,那么应该使用指针的引用或者指向指针的指针。
没有指针的java语言
java语言中使用了引用代替了指针,引用实质就是指针,但它是受控的、安全的。我们知道,一个引用,比如说person p 等于new person,实际上就是p这个引用指向了这个对象实体,所以本质上就是指针。但是这个指针呢,它是安全的,受控制的,也就是说我们这个指针不能乱指,所以,这里面,比如说这个安全性包括了也就是它会检查这个指针是不是空的,是不是null,在这里面有没有指针运算,因为指针运算它很容易就把一个指针再加一点就指向别的地方了,很容易造成内存的错误访问,也不能访问没有引用到的内存,这样才使得那个自动垃圾回收成为可能,因为我们所有的这种引用,都是系统受控制的,都是能够管理的。
C语言指针在java中的体现
(1)传地址 -> 对象
》引用类型,引用本身就相当于指针
~可以用来修改对象的属性,调用对象的方法(我们知道,对象本身是引用型)
》基本类型:没有对应的
~如交换两个整数 ------C语言
~void swap(int x,int y){int t=x;x=y;y=t;} ------C语言
~int a=8,b=9;swap(a,b); ------C语言
~一种变通的方法,传出一个有两个分量x,y的对象(构造一个class,这个class呢有x,y两个分量,那这样的话我们传一个引用过去,然后再把这个引用出来,我们就能得到这两个属性) ------java
(2)指针运算 -> 数组
~*(p+5) 则可以用 args[5]
(3)函数指针 -> 接口、Lambda表达式(接口本质上就是一个约定,那这里函数指针就是一个安全的约定,这个函数它叫什么名字?带什么参数?所以,它本质上是对那个函数指针的一个约定,而lambda函数是这种自动接口的更简洁写法,这个更简洁写法更能体现这个函数指针的概念)
~例:求积分,线程,回调函数,事件处理
(4)指向结点的指针 -> 对象的引用
~class Node{
Object data;
Node next;
}
(5)使用JNI(Java Native Interface)
~它允许java代码和其他语言写的代码进行交互
1 int i=42; 2 int *p; 3 int *&r=p;//指向指针p的引用,就是给指针p取别名r,前面的*号表示引用的是一个指针。 4 5 r=&i; //实际上r就是指针p,对r的操作实际上就是对p的操作,让指针p指向i 6 *r=100;//通过对r进行解引用,实际上修改的是p,对指针p进行解引用,修改的是p所指向的值i
转载于:https://www.cnblogs.com/Dark-King/p/9355082.html
Java引用与C指针的区别
2009-11-02
eNet&Ciweek
首先, 在Java中, 不存在引用传递(也就是地址传递)一说, 全部都是值传递, 自然, 在使用对象时实际上都是使用的引用
Java语言明确说明取消了指针,因为指针往往是在带来方便的同时也是导致代码不安全的根源,同时也会使程序的变得非常复杂难以理解,滥用指针写成的代码不亚于使用早已臭名昭著的"GOTO"语句。Java放弃指针的概念绝对是极其明智的。但这只是在Java语言中没有明确的指针定义,实质上每一个new 语句返回的都是一个指针的引用,只不过在大多时候Java中不用关心如何操作这个"指针",更不用象在操作C++的指针那样胆战心惊。
非也,基本类型数据存放在Stack中,存放的是数据。而产生对象时,只把对象的reference存放在stack中,用于指向某个对象,对象本身存放在Heap中。
还有, 调用方法时传递的参数以及在调用中创建的临时变量都保存在栈(Stack)中,速度较快。其他变量,如静态变量、实例变量等,都在堆(Heap)中创建,速度较慢。另外,依赖于具体的编译器/JVM,局部变量还可能得到进一步优化。
从实现上来讲,引用可以理解为一种受限的指针,引用底层可以采用指针来实现,也可以采用句柄的方式实现。早期jvm一般采用句柄的方式,现在的jvm,比如sun的,IBM的,一般就是用指针来实现。
不过从语言的角度来将,没有必要把java的引用和C的指针来比较。
指针是可以进行与整数做加减运算的,两个指针之间也可以进行大小比较运算和相减运算。
引用不行,只能进行赋值运算。
当然有区别
A a=new A();
你可以 a=a+1;吗? 指针就可以
您对本文或本站有任何意见,请在下方提交,谢谢!