精华内容
下载资源
问答
  • 它们的区别是什么?有什么共性吗?补充:什么时候使用pointer比较好,什么时候用reference? 用pointer和不用有什么区别影响吗?引用是C++引入的重要机制(C语言没有引用),它使原来在C中必须用指针来实现的功能有了另...
    c7aff393e1793ca4e2dbc1ff8c9be8e6.png

    什么是指针pointer,什么是引用reference?它们的区别是什么?有什么共性吗?补充:什么时候使用pointer比较好,什么时候用reference? 用pointer和不用有什么区别影响吗?

    引用是C++引入的重要机制(C语言没有引用),它使原来在C中必须用指针来实现的功能有了另一种实现的选择,在书写形式上更为简洁。那么引用的本质是什么,它与指针又有什么关系呢?

    1.引用的底层实现方式

    引用被称为变量的别名,它不能脱离被引用对象独立存在,这是在高级语言层面的概念和理解,并未解释引用的实现方式。常见错误说法是“引用”自身不是一个变量,甚至编译器可以不以引用分配空间。

    实际上,引用本身是一个变量,只不过这个变量的定义和使用与普通变量有显著的不同。为了解引用变量底层实现机制,考查如下代码:

    int i=5;int &ri=i;ri=8;

    在Visual Studio 2017环境的debug模式调试代码,反汇编查看源码对应的汇编代码的步骤是:调试->窗口->反汇编,即可得到如下原码对应的汇编代码:

    int i=5;00A013DE  mov        dword ptr [i],5    //将文字常量5送入变量iint &ri=i;00A013E5  lea        eax,[i]       //将变量i的地址送入寄存器eax00A013E8  mov        dword ptr [ri],eax  //将寄存器的内容(也就是变量i的地址)送入变量riri=8;00A013EB  mov        eax,dword ptr [ri]  //将变量ri的值送入寄存器eax00A013EE  mov        dword ptr [eax],8   //将数值8送入以eax的内容为地址的单元中return 0;00A013F4  xor        eax,eax

    考查以上代码,在汇编代码中,ri的数据类型为dword,也就是说,ri要在内存中占据4个字节的位置。所以,ri的确是一个变量,它存放的是被引用对象的地址。由于通常情况下,地址是由指针变量存放的,那么,指针变量和引用变量有什么区别呢?使用指针常量实现上面的代码功能。考查如下代码:

    int i=5;int* const pi=&i;*pi=8;

    按照相同的方式,在VS2017中得都如下汇编代码:

    int i=5;011F13DE  mov         dword ptr [i],5  int * const pi=&i;011F13E5  lea         eax,[i]  011F13E8  mov         dword ptr [pi],eax  *pi=8;011F13EB  mov         eax,dword ptr [pi]  011F13EE  mov         dword ptr [eax],8  

    观察以上代码可以看出:

    (1)除了pi与ri变量名不同,所得汇编代码与第一段所对应的汇编代码完全一样。所以,引用变量在功能上等于一个指针常量,即一旦指向某一个单元就不能在指向别处。

    (2)在底层,引用变量由指针按照指针常量的方式实现。

    2.高级语言层面引用与指针常量的关系

    1.引用和指针,在内存中都是占用4个字节(32bits系统中)的存储空间。指针和引用存放的都是被引用对象的地址,都必须在定义的同时进行初始化。

    2.指针常量本身(以p为例)允许寻址,即&p返回指针常量(常变量)本身的地址,被引用对象用*p表示;引用变量本身(以r为例)不允许寻址,&r返回的是被引用对象的地址,而不是变量r的地址(r的地址由编译器掌握,程序员无法直接对它进行存取),被引用对象直接用r表示。

    3.凡是使用了引用变量的代码,都可以转换成使用指针常量的对应形式的代码,只不过书写形式上要繁琐一些。反过来,由于对引用变量使用方式上的限制,使用指针常量能够实现的功能,却不一定能够用引用来实现。

    例如,下面的代码是合法的:

    int i=5,j=6;int* const array[]={&i,&j};

    而如下代码是非法的:

    int i=5,j=6;int& array[]={i,j};

    也就是说,数组元素允许是指针常量,却不允许是引用。C++语言机制如此规定,原因是避免C++语法变得过于晦涩。假如定义一个“引用的数组”,那么array[0]=8;这条语句该如何理解?是将数组元素array[0]本身的值变成8呢,还是将array[0]所引用的对象的值变成8呢?对于程序员来说,这种解释上的二义性对正确编程是一种严重的威胁,毕竟程序员在编写程序的时候,不可能每次使用数组时都要回过头去检查数组的原始定义。

    即得出两个不同:引用只能在定义时被初始化一次,之后不可变,但是指针可变;引用没有 const,指针有 const。

    4.一些其他不同:

    引用使用时无需解引用(*),指针需要解引用;

    “sizeof 引用”得到的是所指向的变量(对象)的大小,而“sizeof 指针”得到的是指针本身(所指向的变量或对象的地址)的大小;

    引用不能为空,指针可以为空;

    指针和引用的自增(++)运算意义不一样;引用自增被引用对象的值,指针自增内存地址。

    展开全文
  • 展开全部java引用与C语言指针e5a48de588b63231313335323631343130323136353331333365643538的区别有以下几方面:1、现象指针在运行时可以改变其所指向的值,而引用一旦和某个对象绑定后就不再改变,总是指向最初的...

    展开全部

    java引用与C语言指针e5a48de588b63231313335323631343130323136353331333365643538的区别有以下几方面:

    1、现象

    指针在运行时可以改变其所指向的值,而引用一旦和某个对象绑定后就不再改变,总是指向最初的对象。

    2、编译

    程序在编译时分别将指针和引用添加到符号表上,符号表上记录的是变量名及变量所对应地址。指针变量在符号表上对应的地址值为指针变量的地址值,而引用在符号表上对应的地址值为引用对象的地址值。符号表生成后就不会再改,因此指针可以改变指向的对象(指针变量中的值可以改),而引用对象不能改。

    3、类型

    引用其值为地址的数据元素,java封装了的地址,可以转成字符串查看,长度可以不必关心;C指针是一个装地址的变量,长度一般是计算机字长,可以认为是个int。

    4、内存占用

    所占内存:引用声明时没有实体,不占空间。C指针如果声明后会用到才会赋值,如果用不到不会分配内存。

    5、内存溢出

    JAVA引用的使用权限比较小,不会产生内存溢出。C指针是容易产生内存溢出的,所以程序员要小心使用,及时回收。

    6、本质

    JAVA中的引用和C中的指针本质上都是想通过一个别名,找到要操作的目标(变量对象等),方便在程序里操作。所不同的是JAVA的办法更安全,使用更加方便些,但没有了C的灵活,高效。

    展开全文
  • 2. 引用与指针的区别 2.1 2.2 2.3 2.4 引用是C++引入的重要机制(C语言没有引用),它使原来在C中必须用指针来实现的功能有了另一种实现的选择,在书写形式上更为简洁。那么引用的本质是什么,它与指针又有什么...

    目录

    1. 引用的底层实现方式

    1.1 从对象出发对引用和指针的理解

    2. 引用与指针的区别

    2.1

    2.2

    2.3

    2.4


    引用是C++引入的重要机制(C语言没有引用),它使原来在C中必须用指针来实现的功能有了另一种实现的选择,在书写形式上更为简洁。那么引用的本质是什么,它与指针又有什么关系呢?

    1. 引用的底层实现方式

    引用被称为变量的别名,它不能脱离被引用对象独立存在,这是在高级语言层面的概念和理解,并未解释引用的实现方式。常见错误说法是“引用”自身不是一个变量,甚至编译器可以不以引用分配空间。

    实际上,引用本身是一个变量,只不过这个变量的定义和使用与普通变量有显著的不同。为了解引用变量底层实现机制,考查如下代码:

    int i=5;
    int &ri=i;
    ri=8;

    在Visual Studio 2017环境的debug模式调试代码,反汇编查看源码对应的汇编代码的步骤是:调试->窗口->反汇编,即可得到如下原码对应的汇编代码:

    int i=5;
    00A013DE  mov        dword ptr [i],5    	//将文字常量5送入变量i
    int &ri=i;
    00A013E5  lea        eax,[i]  	 	    	//将变量i的地址送入寄存器eax
    00A013E8  mov        dword ptr [ri],eax  	//将寄存器的内容(也就是变量i的地址)送入变量ri
    ri=8;
    00A013EB  mov        eax,dword ptr [ri]  	//将变量ri的值送入寄存器eax
    00A013EE  mov        dword ptr [eax],8   	//将数值8送入以eax的内容为地址的单元中
    return 0;
    00A013F4  xor        eax,eax
    

    考查以上代码,在汇编代码中,ri的数据类型为dword,也就是说,ri要在内存中占据4个字节的位置。所以,ri的确是一个变量,它存放的是被引用对象的地址。由于通常情况下,地址是由指针变量存放的,那么,指针变量和引用变量有什么区别呢?使用指针常量实现上面的代码功能。考查如下代码:

    int i=5;
    int* const pi=&i;
    *pi=8;

    按照相同的方式,在VS2017中得都如下汇编代码:

    int i=5;
    011F13DE  mov         dword ptr [i],5  
    int * const pi=&i;
    011F13E5  lea         eax,[i]  
    011F13E8  mov         dword ptr [pi],eax  
    *pi=8;
    011F13EB  mov         eax,dword ptr [pi]  
    011F13EE  mov         dword ptr [eax],8  
    

    观察以上代码可以看出:

    1. 除了pi与ri变量名不同,所得汇编代码与第一段所对应的汇编代码完全一样。所以,引用变量在功能上等于一个指针常量,即一旦指向某一个单元就不能在指向别处。
    2. 在底层,引用变量由指针按照指针常量的方式实现。

    1.1 从对象出发对引用和指针的理解

    C++primer中对 对象的定义:对象是指一块能存储数据并具有某种类型的内存空间
    一个对象a,它有地址&a,运行程序时,计算机会为该对象分配存储空间,来存储该对象的值,我们通过该对象的地址,来访问存储空间中的值

    指针p也是对象,它同样有地址&p和存储的值p,只不过,p存储的数据类型是数据的地址。如果我们要以p中存储的数据为地址,来访问对象的值,则要在p前加解引用操作符"*",即*p。

    我们可以把引用理解成变量的别名。定义一个引用的时候,程序把该引用和它的初始值绑定在一起,而不是拷贝它。计算机必须在声明r的同时就要对它初始化,并且,r一经声明,就不可以再和其它对象绑定在一起了。

    实际上,你也可以把引用看做是通过一个常量指针来实现的,它只能绑定到初始化它的对象上。

    因此,引用的一个优点是它一定不为空,因此相对于指针,它不用检查它所指对象是否为空,这增加了效率。

    综上,引用只是c++语法糖,可以看作编译器自动完成取地址、解引用的常量指针。引用区别于指针的特性都是编译器约束完成的,一旦编译成汇编就和指针一样。

    2. 引用与指针的区别

    2.1

    引用和指针,在内存中都是占用4个字节(32bits系统中)的存储空间。指针和引用存放的都是被引用对象的地址,都必须在定义的同时进行初始化。

    2.2

    指针常量本身(以p为例)允许寻址,即&p返回指针常量(常变量)本身的地址,被引用对象用*p表示;引用变量本身(以r为例)不允许寻址,&r返回的是被引用对象的地址,而不是变量r的地址(r的地址由编译器掌握,程序员无法直接对它进行存取),被引用对象直接用r表示。

    2.3

    凡是使用了引用变量的代码,都可以转换成使用指针常量的对应形式的代码,只不过书写形式上要繁琐一些。反过来,由于对引用变量使用方式上的限制,使用指针常量能够实现的功能,却不一定能够用引用来实现。

    例如,下面的代码是合法的:

    int i=5,j=6;
    int* const array[]={&i,&j};

    而如下代码是非法的:

    int i=5,j=6;
    int& array[]={i,j};

    也就是说,数组元素允许是指针常量,却不允许是引用。C++语言机制如此规定,原因是避免C++语法变得过于晦涩。假如定义一个“引用的数组”,那么array[0]=8;这条语句该如何理解?是将数组元素array[0]本身的值变成8呢,还是将array[0]所引用的对象的值变成8呢?对于程序员来说,这种解释上的二义性对正确编程是一种严重的威胁,毕竟程序员在编写程序的时候,不可能每次使用数组时都要回过头去检查数组的原始定义。

    即得出两个不同:引用只能在定义时被初始化一次,之后不可变,但是指针可变;引用没有 const,指针有 const。

    • 引用没有顶层const即int& const,因为引用本身就不可变,所以在加顶层const也没有意义; 但是可以有底层const即 const int&,这表示引用所引用的对象本身是常量
    • 指针既有顶层const(int* const 指针本身不可变),也有底层const(const int* 指针所指向的对象不可变)

    2.4

    • 尽量用引用代替指针
    • 引用使用时无需解引用(*),指针需要解引用;
    • “sizeof 引用”得到的是所指向的变量(对象)的大小,而“sizeof 指针”得到的是指针本身(所指向的变量或对象的地址)的大小;
    • 引用不能为空,指针可以为空;
    • 指针和引用的自增(++)运算意义不一样;引用代表所指向的对象对象执行++,指针自增内存地址。
    展开全文
  • 它们的区别是什么?有什么共性吗?补充:什么时候使用pointer比较好,什么时候用reference? 用pointer和不用有什么区别影响吗?引用是C++引入的重要机制(C语言没有引用),它使原来在C中必须用指针来实现的功能有了另...
    86e8ca0551071b143b5287169d88d3da.png

    什么是指针pointer,什么是引用reference?它们的区别是什么?有什么共性吗?补充:什么时候使用pointer比较好,什么时候用reference? 用pointer和不用有什么区别影响吗?

    引用是C++引入的重要机制(C语言没有引用),它使原来在C中必须用指针来实现的功能有了另一种实现的选择,在书写形式上更为简洁。那么引用的本质是什么,它与指针又有什么关系呢?

    1.引用的底层实现方式

    引用被称为变量的别名,它不能脱离被引用对象独立存在,这是在高级语言层面的概念和理解,并未解释引用的实现方式。常见错误说法是“引用”自身不是一个变量,甚至编译器可以不以引用分配空间。

    实际上,引用本身是一个变量,只不过这个变量的定义和使用与普通变量有显著的不同。为了解引用变量底层实现机制,考查如下代码:

    int i=5;int &ri=i;ri=8;

    在Visual Studio 2017环境的debug模式调试代码,反汇编查看源码对应的汇编代码的步骤是:调试->窗口->反汇编,即可得到如下原码对应的汇编代码:

    int i=5;00A013DE  mov        dword ptr [i],5    //将文字常量5送入变量iint &ri=i;00A013E5  lea        eax,[i]       //将变量i的地址送入寄存器eax00A013E8  mov        dword ptr [ri],eax  //将寄存器的内容(也就是变量i的地址)送入变量riri=8;00A013EB  mov        eax,dword ptr [ri]  //将变量ri的值送入寄存器eax00A013EE  mov        dword ptr [eax],8   //将数值8送入以eax的内容为地址的单元中return 0;00A013F4  xor        eax,eax

    考查以上代码,在汇编代码中,ri的数据类型为dword,也就是说,ri要在内存中占据4个字节的位置。所以,ri的确是一个变量,它存放的是被引用对象的地址。由于通常情况下,地址是由指针变量存放的,那么,指针变量和引用变量有什么区别呢?使用指针常量实现上面的代码功能。考查如下代码:

    int i=5;int* const pi=&i;*pi=8;

    按照相同的方式,在VS2017中得都如下汇编代码:

    int i=5;011F13DE  mov         dword ptr [i],5  int * const pi=&i;011F13E5  lea         eax,[i]  011F13E8  mov         dword ptr [pi],eax  *pi=8;011F13EB  mov         eax,dword ptr [pi]  011F13EE  mov         dword ptr [eax],8  

    观察以上代码可以看出:

    (1)除了pi与ri变量名不同,所得汇编代码与第一段所对应的汇编代码完全一样。所以,引用变量在功能上等于一个指针常量,即一旦指向某一个单元就不能在指向别处。

    (2)在底层,引用变量由指针按照指针常量的方式实现。

    2.高级语言层面引用与指针常量的关系

    1.引用和指针,在内存中都是占用4个字节(32bits系统中)的存储空间。指针和引用存放的都是被引用对象的地址,都必须在定义的同时进行初始化。

    2.指针常量本身(以p为例)允许寻址,即&p返回指针常量(常变量)本身的地址,被引用对象用*p表示;引用变量本身(以r为例)不允许寻址,&r返回的是被引用对象的地址,而不是变量r的地址(r的地址由编译器掌握,程序员无法直接对它进行存取),被引用对象直接用r表示。

    3.凡是使用了引用变量的代码,都可以转换成使用指针常量的对应形式的代码,只不过书写形式上要繁琐一些。反过来,由于对引用变量使用方式上的限制,使用指针常量能够实现的功能,却不一定能够用引用来实现。

    例如,下面的代码是合法的:

    int i=5,j=6;int* const array[]={&i,&j};

    而如下代码是非法的:

    int i=5,j=6;int& array[]={i,j};

    也就是说,数组元素允许是指针常量,却不允许是引用。C++语言机制如此规定,原因是避免C++语法变得过于晦涩。假如定义一个“引用的数组”,那么array[0]=8;这条语句该如何理解?是将数组元素array[0]本身的值变成8呢,还是将array[0]所引用的对象的值变成8呢?对于程序员来说,这种解释上的二义性对正确编程是一种严重的威胁,毕竟程序员在编写程序的时候,不可能每次使用数组时都要回过头去检查数组的原始定义。

    即得出两个不同:引用只能在定义时被初始化一次,之后不可变,但是指针可变;引用没有 const,指针有 const。

    4.一些其他不同:

    引用使用时无需解引用(*),指针需要解引用;

    “sizeof 引用”得到的是所指向的变量(对象)的大小,而“sizeof 指针”得到的是指针本身(所指向的变量或对象的地址)的大小;

    引用不能为空,指针可以为空;

    指针和引用的自增(++)运算意义不一样;引用自增被引用对象的值,指针自增内存地址。

    展开全文
  • 引用,常量引用,引用与指针的区别引用创建非常量引用创建形参为非常量引用的交换函数创建常量引用引用与指针的区别什么时候使用引用?和什么时候使用指针?1.使用引用参数的主要原因2.对于使用传递的值而不做修改的...
  • 指针与引用是C++中两个很重要概念,它们功能看过去很相似,就是都间接引用某个对象,那么我们应该在什么时候使用指针什么时候使用引用呢,下面请允许我慢慢道来:1.永远不要使用一个指向空值的引用。一个引用...
  • Java引用与C指针的区别如下:1、现象指针在运行时可以改变其所指向的值(地址)即指向其它变量,而引用一旦和某个对象绑定后就不能再改变,总是指向最初的对象。2、编译程序在编译时分别将指针和引用添加到符号表上,...
  • 指针通过某个指针变量指向一个对象后,对它所指向变量间接操作。程序中使用指针,程序可读性差; 而引用本身就是目标变量别名,对引用的操作就是对目标变量操作。
  • 引用 引用的特性 引用与指针的区别 什么是引用 > 引用 可以看做给变量取了别名 int &a=b; 引用的特性 必须在定义时初始化 一个变量可以有多个引用 引用了一个变量之后不能再引用其他变量 常引用 常...
  • 指针指向一块内存,它内容所指内存地址;引用是某块内存别名。 区别: 1. 指针是一个实体,而引用个别名; 2. 引用使用时无需解引用(*),指针需要解引用; 3. 引用只能在定义时被初始化一次,之后不可变...
  • 引用与指针的区别

    2021-03-14 01:54:58
    指针:存放变量地址一个变量,在逻辑上独立,它可以被改变,包括其所指向地址改变和其指向地址中所存放数据改变 ...引用本质上一个指针常量,在内存中为引用开辟了一个指针内存单元 ...
  • 经常会有人问道C++中指针与引用的区别,自己在学习C++过程中也经常会有这种困惑。现总结一下。知识点回忆C++中对对象的定义:指一块能存储数据并且具有某种类型的内存空间。一个对象a,它有值和地址&a,运行...
  • 引用与指针什么区别

    万次阅读 多人点赞 2019-06-25 15:41:42
    引用与指针什么区别? 指针和引用都地址概念,指针指向一块内存,它内容所指内存地址;引用某块内存别名。 程序为指针变量分配内存区域,而不为引用分配内存区域。 指针使用时要在前加 * ,引用...
  • 前面整理了指针的用法,但是经常和指针拿来对比东西是引用。确实指针在使用的过程中会有很多的麻烦,比如赋初值、使用时判空、无效指针、深浅拷贝等等。在我看来引用指针的高级替代,它的使用规则规避了很多出错的...
  • 指针引用的联系与区别 ★ 相同点: 1. 都地址概念; 指针指向一块内存,它内容所指内存地址;引用是某块内存别名。 ★ 区别: 1. 指针是一个实体,而引用个别名; 2. 引用使用时无需解引用(*),...
  • 引用最初定义:引用是一种特殊类型变量,可以认为另一个变量别名,通过引用通过被引用的变量名访问效果一样。 C++对指针进行简单封装引入了引用。 程序运行时,变量只能依靠地址来区别,只有通过...
  • 2.1本质:引用是别名,指针是地址2.2具体:2.2.1 从现象上看:指针在运行时可以改变所指向值,而引用一旦某个对象绑定后就不再改变。意思指针可以被重新赋值以指向另一个对象,但是引用则总是在初始化时被...
  • 引用与指针什么区别? 1、指针一个实体,而引用仅个别名; 2、引用使用时无需解引用(*),指针需要解引用; 3、引用只能在定义时被初始化一次,之后不可变;指针可变; 4、引用没有const,指针有const; ...
  • C++中引用与指针的区别

    万次阅读 多人点赞 2017-02-11 10:35:59
    学过C的朋友应该都知道指针,刚开始学习指针的时候,都会觉得指针很难,学完了指针才发现指针就是保存的地址。指针十分不安全,使用的不恰当,就会使程序出错!C++里面提出了“引用”代替指针,提高程序的安全性。...
  • 引用不是新定义一个变量,而是给已经存在变量取了一个别名,编译器不回为引用开辟一个新空间,引用与实体共用同一块内存。 举个例子: void Swap(int& x) { x = 2; cout << "x...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,024
精华内容 409
关键字:

引用与指针的区别是什么