指针与引用的区别(摘自Effective-C )
- 格式:pdf
- 大小:344.96 KB
- 文档页数:3
c++中,引用和指针的区别(1)引用总是指向一个对象,没有所谓的null reference .所有当有可能指向一个对象也由可能不指向对象则必须使用指针.由于C++ 要求reference 总是指向一个对象所以reference要求有初值.String & rs = string1;由于没有所谓的null reference 所以所以在使用前不需要进行测试其是否有值.,而使用指针则需要测试其的有效性.(2)指针可以被重新赋值而reference则总是指向最初或地的对象.(3)必须使用reference的场合. Operator[] 操作符由于该操作符很特别地必须返回[能够被当做assignment 赋值对象] 的东西,所以需要给他返回一个reference.(4)其实引用在函数的参数中使用很经常.void Get***(const int& a) //这样使用了引用有可以保证不修改被引用的值{}引用和指针★相同点:1. 都是地址的概念;指针指向一块内存,它的内容是所指内存的地址;引用是某块内存的别名。
★区别:1. 指针是一个实体,而引用仅是个别名;2. 引用使用时无需解引用(*),指针需要解引用;3. 引用只能在定义时被初始化一次,之后不可变;指针可变;引用“从一而终” ^_^4. 引用没有const,指针有const,const 的指针不可变;5. 引用不能为空,指针可以为空;6. “sizeof 引用”得到的是所指向的变量(对象)的大小,而“sizeof 指针”得到的是指针本身(所指向的变量或对象的地址)的大小;typeid(T) == typeid(T&) 恒为真,sizeof(T) == sizeof(T&) 恒为真,但是当引用作为成员时,其占用空间与指针相同(没找到标准的规定)。
7. 指针和引用的自增(++)运算意义不一样;★联系1. 引用在语言内部用指针实现(如何实现?)。
引用与指针有什么区别
引用与指针有什么区别?
首先,引用必须被初始化,指针不必。
其次,引用不可以为空,但指针可以为空。
引用是对象的别名,引用为空——对象都不存在,怎么可能有别名!故定义一个引用的时候,必须初始化。
其次,引用初始化以后不能被改变,指针可以改变所指的对象。
再次,引用的大小是所指向的变量的大小,因为引用只是一个别名而已;指针是指针本身的大小,4个字节
最后,引用比指针更安全。
由于不存在空引用,并且引用一旦被初始化为指向一个对象,它就不能被改变为另一个对象的引用,因此引用很安全
指针和引用的相同点和不同点:
★相同点:
●都是地址的概念;
指针指向一块内存,它的内容是所指内存的地址;而引用则是某块内存的别名。
★不同点:
●指针是一个实体,而引用仅是个别名;
●引用只能在定义时被初始化一次,之后不可变;指针可变;引用“从一而终”,指针可以“见异思迁”;
●引用没有const,指针有const,const的指针不可变;(具体指没有int& const a这种形式,而const int& a是有的,前者指引用本身即别名不可以改变,这是当然的,所以不需要这种形式,后者指引用所指的值不可以改变)
●引用不能为空,指针可以为空;
●“sizeof 引用”得到的是所指向的变量(对象)的大小,而“sizeof 指针”得到的是指针本身的大小;
●指针和引用的自增(++)运算意义不一样;
●引用是类型安全的,而指针不是 (引用比指针多了类型检查。
C++中引⽤传递与指针传递的区别(⾯试常见)最近Garena⾯试的过程中,⾯试官提了⼀个问题,C++中引⽤传递和指针传递的区别?根据⾃⼰的经验,联想到了swap函数,只知道既可以⽤引⽤来实现,⼜可以⽤指针传递来实现,⾄于⼆者有何区别,⾃⼰还真没有考虑过。
痛定思痛,受虐之后,赶紧弥补⾃⼰的知识漏洞。
通过在⽹上搜集资料,⾃⼰也整理了⼀下。
精简版:指针:变量,独⽴,可变,可空,替⾝,⽆类型检查;引⽤:别名,依赖,不变,⾮空,本体,有类型检查;完整版:1. 概念 指针从本质上讲是⼀个变量,变量的值是另⼀个变量的地址,指针在逻辑上是独⽴的,它可以被改变的,包括指针变量的值(所指向的地址)和指针变量的值对应的内存中的数据(所指向地址中所存放的数据)。
引⽤从本质上讲是⼀个别名,是另⼀个变量的同义词,它在逻辑上不是独⽴的,它的存在具有依附性,所以引⽤必须在⼀开始就被初始化(先有这个变量,这个实物,这个实物才能有别名),⽽且其引⽤的对象在其整个⽣命周期中不能被改变,即⾃始⾄终只能依附于同⼀个变量(初始化的时候代表的是谁的别名,就⼀直是谁的别名,不能变)。
2. C++中的指针参数传递和引⽤参数传递 指针参数传递本质上是值传递,它所传递的是⼀个地址值。
值传递过程中,被调函数的形式参数作为被调函数的局部变量处理,会在栈中开辟内存空间以存放由主调函数传递进来的实参值,从⽽形成了实参的⼀个副本(替⾝)。
值传递的特点是,被调函数对形式参数的任何操作都是作为局部变量进⾏的,不会影响主调函数的实参变量的值(形参指针变了,实参指针不会变)。
引⽤参数传递过程中,被调函数的形式参数也作为局部变量在栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址。
被调函数对形参(本体)的任何操作都被处理成间接寻址,即通过栈中存放的地址访问主调函数中的实参变量(根据别名找到主调函数中的本体)。
因此,被调函数对形参的任何操作都会影响主调函数中的实参变量。
引用和用指针的区别在c++函数中,形式参数用引用和用指针都可以起到在被调用函数中改变调用函数的变量的作用。
什么时候用引用作参数什么时候用指针作参数呢 void function (int *ptr); void function(int &ref);没有特定的规定。
学的久了,就会习惯什么时候用指针什么时候用引用了引用与指针有什么区别? 1) 引用必须被初始化,指针不必。
2) 引用初始化以后不能被改变,指针可以改变所指的对象。
2) 不存在指向空值的引用,但是存在指向空值的指针。
C++中尽量用引用。
个人觉得所有的引用都可以用指针,但指针比引用容易出错。
引用当然更直观更直接,做参数时,如果在函数内不刻意要用指针的那些副作用(如越界访问,动态定向什么的),引用可以代替指针。
C++ 中一般都用引用就可以了 ... C 中没有引用,就使用指针 ....举例如下: 1 使用指针传递参数时: void function (int *ptr) { 函数体;} 调用该函数时 main() { int p; function (&p); } 2 使用引用传递参数时: void function(int &ref) { 函数体;} 调用该函数时 main() { int p; function (p); } 由此可见,使用引用比使用指针传递参数函数调用时更简单,引用和指针功能大体相同,但是有空间分配时建议最好使用指针,因为在释放空间时,对指针只需要delete就行了,而引用是不能删除空间的,引用必须指向一个存在的对象。
指针和引用的差别 1. 非空的差别任何情况下都不能使用指向空值的引用.一个引用必须总是指向某个对象. 不存在的指向空值的引用这个事实意味着使用引用的代码效率比使用指针要高. 2. 合法性区别在使用引用之前不需要测试他的合法性.指针必须测试. 3. 可修改区别指针可以被重新赋值给另一个不同的对象.但是引用总是指向在初始化的时候被制定的对象,以后不能改变.但是指定的对象其内容可以改变. 应该使用指针的情况: 可能存在不指向任何对象的可能性需要在不同的时刻指向不同的对象(此时,你能够改变指针的指向) 应该使用引用的情况: 如果总是指向一个对象并且一旦指向一个对象后就不会改变指向,使用此时应使用引用。
浅谈CC++引⽤和指针的联系和区别为什么C/C++语⾔使⽤指针?答案:①⼀⽅⾯,每⼀种编程语⾔都使⽤指针。
不⽌C/C++使⽤指针。
每⼀种编程语⾔都使⽤指针。
C++将指针暴露给了⽤户(程序员),⽽Java和C#等语⾔则将指针隐藏起来了。
“Everything uses pointers. C++ just exposes them rather than hiding them,”It's easier to give someone an address to your home than to give a copy of your home to everyone.②另⼀⽅⾯使⽤指针的优点和必要性:指针能够有效的表⽰数据结构;能动态分配内存,实现内存的⾃由管理;能较⽅便的使⽤字符串;便捷⾼效地使⽤数组指针直接与数据的储存地址有关,⽐如:值传递不如地址传递⾼效,因为值传递先从实参的地址中取出值,再赋值给形参代⼊函数计算;⽽指针则把形参的地址直接指向实参地址,使⽤时直接取出数据,效率提⾼,特别在频繁赋值等情况下(注意:形参的改变会影响实参的值!)引⽤和指针有什么区别?本质:引⽤是别名,指针是地址,具体的:①从现象上看,指针在运⾏时可以改变其所指向的值,⽽引⽤⼀旦和某个对象绑定后就不再改变。
这句话可以理解为:指针可以被重新赋值以指向另⼀个不同的对象。
但是引⽤则总是指向在初始化时被指定的对象,以后不能改变,但是指定的对象其内容可以改变。
②从内存分配上看,程序为指针变量分配内存区域,⽽不为引⽤分配内存区域,因为引⽤声明时必须初始化,从⽽指向⼀个已经存在的对象。
引⽤不能指向空值。
注:标准没有规定引⽤要不要占⽤内存,也没有规定引⽤具体要怎么实现,具体随编译器 /topics/320095541③从编译上看,程序在编译时分别将指针和引⽤添加到符号表上,符号表上记录的是变量名及变量所对应地址。
指针变量在符号表上对应的地址值为指针变量的地址值,⽽引⽤在符号表上对应的地址值为引⽤对象的地址值。
引用实际上就是给同一个变量取了多个名字。
举个例子:有个人的名字叫a,之后又改名叫b,这时a和b都是指这个人,这样b就引用了a,即b就是a。
引用即别名,与原来的对象使用同样的存储单元,声明的同时必须定义,而且之后不能重新定义(在作用域里)取地址是一种初始化指针的操作,所以:Int &a=b; (1)int *a=&b; (2)在1的情况下,只分配了b的空间在2的情况下,分配了a和b的空间引用是C++的叫法取地址是C的叫法简单说:引用,需要一个对象;取地址,不用。
另:把引用说是指针,也不为过。
其区别可以这么说:引用不能改变,指针可以改变。
引用有安全机制检查,指针没有。
引用的两大作用:1)作为函数的参数,用于提高效率(如常量入参,返回类的成员变量的值)、返回数据...作为函数的参数,用于提高效率这里主要是指用类实例作为参数,因为如果不是用引用,也不使用指针,那么在参数的传递过程中,将有一个隐含的调用类的构造函数的操作,也就是说将构造一个新的类作为参数,使用引用将避免这个过程,如果担心类中的成员被修改,那么可以再加上const修饰符。
2)简化代码,使代码易读。
如:要使用a->b->c->d->e->f->g,g是一个多重嵌套类中的一个整数成员,书写很麻烦,也容易错。
这时: int &z=a->b->c->d->e->f->g;以后直接使用z,因为他们的存贮单元本来一致,所以也根本没有效率的损失。
//------------>怎样理解引用的作用和意义.你是否感觉:&在几个用法中没有一致的性质可循.下面我们就来探讨和总结一下:#include <iostream>#include <stdio.h>using namespace std;void main(void){//测试引用是否可以赋以常量.//考察引用和指针的使用区别//测试对引用取址返回的结果//测试是否可以重新赋值//说明引用的一种错误用法..........//测试引用和指针混合的情况...typedef char* PChar;typedef char& RChar;typedef PChar& RPChar;PChar str = "I am programming.";RPChar rpchar = str;cout<<str<<endl<<rpchar<<endl;getchar();}*/*******************************************************/*结论:对于int & a;引用实际是一种隐式指针,是方便编程而引入的,识别由编译器支持。
c高级面试题及答案C高级面试题及答案1. 问题:请解释C语言中的指针和引用的区别。
答案:在C语言中,指针是一个变量,它存储了另一个变量的内存地址。
指针可以被重新赋值为其他地址,也可以被解引用,访问或修改它所指向的内存中的数据。
而引用在C语言中并不存在,这是C++的一个特性。
在C++中,引用是一个别名,它为一个已存在的变量提供了另一个名字。
一旦引用被初始化,它就不能被重新赋值为另一个变量的引用,也不能被解引用,因为引用本身就是别名。
2. 问题:C语言中如何实现函数的递归调用?答案:在C语言中,实现函数的递归调用需要在函数内部调用自身。
递归函数通常包含一个或多个终止条件,以防止无限递归。
例如,计算阶乘的递归函数可以这样实现:```cint factorial(int n) {if (n == 0) return 1; // 终止条件return n * factorial(n - 1); // 递归调用}```3. 问题:解释C语言中的结构体和联合体的区别。
答案:结构体(struct)和联合体(union)都是C语言中用于创建自定义数据类型的复合数据结构。
结构体可以包含不同类型的多个成员,每个成员都占据自己的内存空间。
联合体则是一种特殊的结构体,它允许所有成员共享相同的内存位置。
在任何时刻,联合体只能存储一个成员的值,这个值的类型决定了联合体的大小。
4. 问题:C语言中如何实现多线程编程?答案:C语言本身不直接支持多线程编程,但可以通过使用POSIX 线程库(pthreads)来实现。
首先需要包含头文件`<pthread.h>`,然后定义线程函数,创建和初始化线程,最后同步线程的执行。
例如: ```c#include <pthread.h>void* thread_function(void* arg) {// 线程执行的代码return NULL;}int main() {pthread_t thread_id;pthread_create(&thread_id, NULL, thread_function, NULL);pthread_join(thread_id, NULL);return 0;}```5. 问题:什么是C语言中的静态存储类?答案:静态存储类(static)在C语言中用于控制变量和函数的生命周期和作用域。
指针与引用1.引用:所关联对象的另一个名字,引用主要用作函数的形式参数;不能定义引用类型的引用;(1) 引用必须用与该引用同类型的对象初始化:例:int ival = 1024;int &refval = ival; //正确:refval与对象ival关联int &refval2; //错误:定义引用必须初始化int &refval3 = 10; //错误:必须使用对象初始化引用(2) 作用在引用上的操作实际上都是作用在该引用关联的对象上:例:refval += 2; //实际上是将ival加2int i = refval; //把ival的值赋给irefval = 5; //修改ival的值为52.const引用:指向const对象的引用例:const int ival1 = 1024;int ival2 = 256;const int &refval1 = ival1; //正确:const引用关联const对象 //正确:const引用关联非const对象const int &refval2 = ival2;int &refval3 = ival1; //错误:非const引用不能关联const对象int &refval4 = ival2; //正确:非const引用关联非const对象注:可以读取但不能修改refval1,任何对refval1的赋值都是不合法的;不能直接对ival1赋值,也不能通过refval1来修改ival1。
(1) const引用:指向const对象的引用,但也可以关联非const相关类型的对象或字面值常量(指向const对象的引用可以用字面值常量初始化);例:int ival = 42;/* const引用关联字面值常量,r1 = 42,值不可修改,但可以赋给其它引用或变量 */const int &r1 = 42;const int &r2 = r1 + ival; //const引用关联非const同类型对象double dval = 3.14;const int &r3 = dval; //const引用关联非const相关类型对象(2) 非const引用:指向非const对象的引用,只能关联到与该引用同类型的对象(指向非const对象的引用只能用非const对象初始化)。
C++中引用传递与指针传递区别在C++中,指针和引用经常用于函数的参数传递,然而,指针传递参数和引用传递参数是有本质上的不同的:指针传递参数本质上是值传递的方式,它所传递的是一个地址值。
值传递过程中,被调函数的形式参数作为被调函数的局部变量处理,即在栈中开辟了内存空间以存放由主调函数放进来的实参的值,从而成为了实参的一个副本。
值传递的特点是被调函数对形式参数的任何操作都是作为局部变量进行,不会影响主调函数的实参变量的值。
(这里是在说实参指针本身的地址值不会变)而在引用传递过程中,被调函数的形式参数虽然也作为局部变量在栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址。
被调函数对形参的任何操作都被处理成间接寻址,即通过栈中存放的地址访问主调函数中的实参变量。
正因为如此,被调函数对形参做的任何操作都影响了主调函数中的实参变量。
引用传递和指针传递是不同的,虽然它们都是在被调函数栈空间上的一个局部变量,但是任何对于引用参数的处理都会通过一个间接寻址的方式操作到主调函数中的相关变量。
而对于指针传递的参数,如果改变被调函数中的指针地址,它将影响不到主调函数的相关变量。
如果想通过指针参数传递来改变主调函数中的相关变量,那就得使用指向指针的指针,或者指针引用。
为了进一步加深大家对指针和引用的区别,下面我从编译的角度来阐述它们之间的区别:程序在编译时分别将指针和引用添加到符号表上,符号表上记录的是变量名及变量所对应地址。
指针变量在符号表上对应的地址值为指针变量的地址值,而引用在符号表上对应的地址值为引用对象的地址值。
符号表生成后就不会再改,因此指针可以改变其指向的对象(指针变量中的值可以改),而引用对象则不能修改。
最后,总结一下指针和引用的相同点和不同点:★相同点:●都是地址的概念;指针指向一块内存,它的内容是所指内存的地址;而引用则是某块内存的别名。
★不同点:●指针是一个实体,而引用仅是个别名;●引用只能在定义时被初始化一次,之后不可变;指针可变;引用“从一而终”,指针可以“见异思迁”;●引用没有const,指针有const,const的指针不可变;(具体指没有int& const a这种形式,而const int& a是有的,前者指引用本身即别名不可以改变,这是当然的,所以不需要这种形式,后者指引用所指的值不可以改变)●引用不能为空,指针可以为空;●“sizeof 引用”得到的是所指向的变量(对象)的大小,而“sizeof 指针”得到的是指针本身的大小;typeid(T)== typeid(T&)恒为真,sizeof(T)==sizeof(T&)恒为真,但是当引用作为成员时,其占用空间与指针相同(没找到标准的规定)●指针和引用的自增(++)运算意义不一样;●引用是类型安全的,而指针不是,引用比指针多了类型检查★联系1. 引用在语言内部用指针实现(如何实现?)。
C++中引⽤和指针的区别c++中的引⽤详解什么是引⽤?引⽤是C++语⾔的⼀个特殊的数据类型描述,⽤于在程序的不同的部分使⽤两个以上的变量名指向同⼀块地址,使得对其中任何⼀个变量的操作实际上都是对同⼀地址单元进⾏的。
使⽤时的注意事项:引⽤的特点:1.⼀个变量可取多个别名。
2.引⽤必须初始化。
3.引⽤只能在初始化的时候引⽤⼀次,不能更改为转⽽引⽤其他变量。
4.对引⽤进⾏操作,实际上就是对被引⽤的变量进⾏操作,5.引⽤仅是变量的别名,⽽不是实实在在地定义了⼀个变量,因此引⽤本⾝并不占⽤内存,⽽是和⽬标变量共同指向⽬标变量的内存地址.声明引⽤时,⽬标的存储状态不会改变6.表达式中的取地址符&不再是取变量的地址,⽽是⽤来表⽰该变量是引⽤类型的变量。
引⽤的应⽤:1.基础引⽤:1 2 3 4 5 6 7 8 9 10void TestReference1 (){int a = 1;int& b = a; b=2;cout<<"a:address->"<<&a<< endl; cout<<"b:address->"<<&b<< endl; //输出结果a,b都等于2}2.const引⽤: 常引⽤声明⽅式:const 类型标识符 &引⽤名 = ⽬标变量名; ⽤这种⽅式声明的引⽤,不能通过引⽤对⽬标变量的值进⾏修改,从⽽使引⽤的⽬标成为const,达到了引⽤的安全性。
1 2 3 4 5 6 7 8 9 10 11#include<iostream.h>void main(){int a=1;int&b=a;b=2;cout<<"a="<<a<<endl;//2int c=1;const int&d=c;// d=2;//编译错误 error C2166: l-value specifies const object c=2;//正确} 这不光是让代码更健壮,也有其它⽅⾯的需求。
一概括指针和引用,在C++的软件开发中非常常见,如果能恰当的使用它们能够极大的提高整个软件的效率,但是很多的C++学习者对它们的各种使用情况并不是都了解,这就导致了实际的软件开发中经常会内存泄漏,异常抛出,程序崩溃等问题。
对于C和C++的初学者,那更是被它们搞的迷迷糊糊。
本篇作为[深入 C++]系列的第一节,我们就带领大家把指针和引用这个基本功练好。
二指针指针,指针的定义是什么呢?好像要想给个直接的定义还是很难的哦,所以我们这里用它的语法结合图来认识它。
int i = 10;int *p = NULL;p = &i;int j = *p; int **pP = NULL; pP = &p;在上面的几条语句中,&用来定义引用变量或对变量取其地址,*用来定义指针或得到指针所指向的变量,其中p为定义的指针变量,它指向int变量i,而pP 为二级指针变量,它指向指针变量p。
相应的示意图如下:C++是对C的扩展,我们首先来看指针在C中的使用,下面的经典实例来自林锐的《高质量编程》,记住函数的默认参数传递方式为按值传递,即实参被传入函数内时进行了拷贝,函数内其实是对拷贝对象的操作,还有当函数使用return 返回变量时,其实返回的是原对象的一个拷贝,此时的实参和原对象有可能是一般变量也有可能是指针变量。
Code<!-- <br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />/<br /><br/>-->#pragma once#include < cstring >#include < cstdio >#include < cstdlib >// -----------------------------------------------void GetMemory1( char * p, int num){p = ( char * )malloc(num);}void Test1( void ){char * str = NULL;GetMemory1(str, 100 );strcpy(str, "hello world" );printf(str);}// -----------------------------------------------void GetMemory2( char ** p, int num){* p = ( char * )malloc(num);}void Test2( void ){char * str = NULL;GetMemory2( & str, 100 );strcpy(str, "hello world" );printf(str);free(str);}// -----------------------------------------------char * GetMemory3( void ){char p[] = "hello world" ;return p;}void Test3( void ){char * str = NULL;str = GetMemory3();printf(str);}// -----------------------------------------------char * GetMemory4( void ){char * p = "hello world" ;return p;}void Test4(){char * str = NULL;str = GetMemory4();printf(str);}// -----------------------------------------------char * GetMemory5( void ){char * p = ( char * )malloc( 100 );strcpy(p, "hello world" );return p;}void Test5(){char * str = NULL;str = GetMemory5();printf(str);free(str);}// -----------------------------------------------void Test6( void ){char * str = ( char * )malloc( 100 );strcpy(str, "hello" );free(str);if (str != NULL){strcpy(str, "world" );printf(str);}}// -----------------------------------------------void TestPointerAndReference(){// -----------------------------------------------//请问运行Test1函数会有什么样的结果?////答:程序崩溃。
Overload(重载):在C++程序中,可以将语义、功能相似的几个函数用同一个名字表示,但参数或返回值不同(包括类型、顺序不同),即函数重载。
(1)相同的范围(在同一个类中);(2)函数名字相同;(3)参数不同;(4)virtual 关键字可有可无。
Override(覆盖):是指派生类函数覆盖基类函数,特征是:(1)不同的范围(分别位于派生类与基类);(2)函数名字相同;(3)参数相同;(4)基类函数必须有virtual 关键字。
Overwrite(重写):是指派生类的函数屏蔽了与其同名的基类函数,规则如下:(1)如果派生类的函数与基类的函数同名,但是参数不同。
此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。
(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字。
此时,基类的函数被隐藏(注意别与覆盖混淆)。
特别注意如果基类有某个函数的多个重载(overload)版本,而你在子类中重写(overwrite)了其中的一个,或是子类添加新的函数版本,则所有基类的重载版本都被遮蔽。
所以,正常情况下,在子类中应重写基类中的所有重载版本。
具体地讲,继承类中的重载和重写都包含了重写的涵义,即只要函数名一样,基类的函数版本就会被遮蔽,所以,在派生类中要保持基类的重载版本,就应该重写所有基类的重载版本。
重载只在当当前类中有效,继承会失去重载的特性。
也就是说,把基类的重载函数放在继承类里,就必须重写。
指针和引用的区别总结1.从现象上看:指针在运行时可以改变其所指向的值,而引用一旦和某个对象绑定后就不再改变2.从内存分配上看:程序为指针变量分配内存区域,而引用不分配内存区域3. 从编译上看:程序在编译时分别将指针和引用添加到符号表上,符号表上记录的是变量名及变量所对应地址。
指针变量在符号表上对应的地址值为指针变量的地址值,而引用在符号表上对应的地址值为引用对象的地址值。
C++中指针和引用的区别
指针和引用的定义和性质区别:
(1)指针:指针是一个变量,只不过这个变量存储的是一个地址,指向内存的一个存储单元;而引用跟原来的变量实质上是同一个东西,只不过是原变量的一个别名而已。
如:
int a=1;int *p=&a;
int a=1;int &b=a;
上面定义了一个整形变量和一个指针变量p,该指针变量指向a 的存储单元,即p 的值是a 存储单元的地址。
而下面2 句定义了一个整形变量a 和这个整形a 的引用b,事实上a 和b 是同一个东西,在内存占有同一个存储单元。
C引⽤和指针的区别
指针和引⽤在C++中很常⽤,但是对于它们之间的区别很多初学者都不是太熟悉,下⾯来谈谈他们2者之间的区别和⽤法。
指针和引⽤的定义和性质区别:
1. 指针:指针是⼀个变量,只不过这个变量存储的是⼀个地址,指向内存的⼀个存储单元;⽽引⽤跟原来的变量实质上是同⼀个东西,
只不过是原变量的⼀个别名⽽已。
如:
int a=1;int *p=&a;
int a=1;int &b=a;
上⾯定义了⼀个整形变量和⼀个指针变量p,该指针变量指向a的存储单元,即p的值是a存储单元的地址。
⽽下⾯2句定义了⼀个整形变量a和这个整形a的引⽤b,事实上a和b是同⼀个东西,在内存占有同⼀个存储单元。
2. 可以有const指针,但是没有const引⽤;
3. 指针可以有多级,但是引⽤只能是⼀级(int **p;合法⽽ int &&a是不合法的)
4. 指针的值可以为空,但是引⽤的值不能为NULL,并且引⽤在定义的时候必须初始化;
5. 指针的值在初始化后可以改变,即指向其它的存储单元,⽽引⽤在进⾏初始化后就不会再改变了。
6. "sizeof引⽤"得到的是所指向的变量(对象)的⼤⼩,⽽"sizeof指针"得到的是指针本⾝的⼤⼩;
7. 指针和引⽤的⾃增(++)运算意义不⼀样。
总结:
指针是指向变量地址⽽不⽤储存变量的内容⽽占⽤更多空间(就像sql⾥⾯的id字段,通过id就可以查询到这条数据,⽽不需要再储存⼀次这条数据)。
引⽤就是相当于别名,给他另外起⼀个名字。
但是还是他⾃⼰。
引⽤和指针⼀、引⽤引⽤(reference)为对象起另外⼀个名字,引⽤类型另外⼀种类型,将声明符写成&d的形式来定义引⽤,d是声明的变量名。
引⽤必须被初始化。
例如:int ival = 1024;int &refVal = ival;//refVal指向ival,是ival的另⼀个名字。
注意:引⽤并⾮对象,只是为⼀个已经存在的对象所起的另外⼀个名字。
给引⽤赋值,实际上是值赋给了与之绑定的对象。
由于引⽤本⾝不是⼀个对象,所以不能定义引⽤的引⽤。
引⽤只能绑定在对象上,不能与字⾯值或某个表达式的计算结果绑定在⼀起。
引⽤类型要与引⽤对象的类型⼀致。
⼆、指针指针是⼀种指向另外⼀种类型的复合类型,指针类型被⽤于指定它所指向的类型,两者类型必须⼀致。
指针的值(即地址)应属于下列四种状态之⼀:1、指向⼀个对象2、指向紧邻对象所占空间的下⼀个位置3、空指针,指针没有指向如何对象4、⽆效指针,即上述情况之外的其他值空指针:不指向任何对象。
⽣成空指针⽅法如下:1int *p1 = nullptr;//等价于int *p1=02int *p2=0;//直接将p2初始化为字⾯值常量03//需要#include <cstdlib.h>4int *p3 = NULL;//等价于int *p3 = 0;初始化所有的指针。
void* 指针是⼀种特殊的指针类型,可⽤于存放任意对象的地址。
三、指针和引⽤的主要区别1. 引⽤总是指向某个确定的对象,定义引⽤时没有进⾏初始化会出现编译错误;2. 赋值⾏为上存在差异:给引⽤赋值修改的是该引⽤所关联的对象的值,引⽤⼀经初始化,就始终指向同⼀个特定对象。
给指针赋值修改的是指针对象本⾝,也就是使指针指向另⼀个对象,指针在不同时刻可指向不同的对象。
四、指向指针的指针指针是内存的对象,允许把指针的地址存放在另⼀个指针当中五、指向指针的引⽤引⽤本⾝不是⼀个对象,因此不能定义指向引⽤的指针。
C语言指针和引用的不同之处
先解决两个疑问
◆指针和引用的不同之处是什么?
◆什么时候用指针?什么时候用引用?
指针和引用的不同之处
看如下代码:
指针是用来表示内存地址的,而指针这个整数正是被指向的变量地址。
而引用就是给变量重新起了一个名字,引用也就是“别名”。
不同之处
◆指针在声明时可以暂时不初始化,当然每次使用指针时都要做检查,以防出现空指针异常的问题。
而引用永远都不会为空,它一定得代表某个对象。
◆指针存放的是地址,可以被重新赋值。
而引用总是指向它最初代表的那个对象。
指针和引用使用场合
引用主要是作为函数的参数和返回值来使用的,看如下代码:
通过vec[3] =3可改变vector容器的值,这是因为[]操作符返回的就是引用。
也就是为内部的变量取了一个别名,还能让[]操作符返回一个指针,
即*vec[3] = 3。
实际上引用可以做的事情指针都可以做,那为什么还要使用引用?
总结
用恰当的工具做恰如其分的工作。
指针可以毫无约束的操作内存中的任何东西,功能十分强大,但也很危险,所以可以在恰当的时机使用引用。
当你需要指向某个东西,绝不会让其指向其它东西,例如有些函数参数为了避免拷贝可以使用引用,或者实现一个操作符而其语法需求无法由指针达成,
例如vec[3] = 3,可以使用引用,而其它任何时候,都要使用指针。
★相同点:1. 都是地址的概念;指针指向一块内存,它的内容是所指内存的地址;引用是某块内存的别名。
★区别:1. 指针是一个实体,而引用仅是个别名;2. 引用使用时无需解引用(*),指针需要解引用;3. 引用只能在定义时被初始化一次,之后不可变;指针可变;引用“从一而终”4. 引用没有const,指针有const,const 的指针不可变;5. 引用不能为空,指针可以为空;6. “sizeof 引用”得到的是所指向的变量(对象)的大小,而“sizeof 指针”得到的是指针本身(所指向的变量或对象的地址)的大小;typeid(T)== typeid(T&)恒为真,sizeof(T)== sizeof(T&)恒为真,但是当引用作为成员时,其占用空间与指针相同(没找到标准的规定)。
7.指针和引用的自增(++)运算意义不一样;★联系1. 引用在语言内部用指针实现(如何实现?)。
2. 对一般应用而言,把引用理解为指针,不会犯严重语义错误。
引用是操作受限了的指针(仅容许取内容操作)。
引用是C++中的概念,初学者容易把引用和指针混淆一起。
一下程序中,n 是m 的一个引用(reference),m 是被引用物(referent)。
int m;int &n = m;n 相当于m 的别名(绰号),对n 的任何操作就是对m 的操作。
例如有人名叫王小毛,他的绰号是“三毛”。
说“三毛”怎么怎么的,其实就是对王小毛说三道四。
所以n 既不是m 的拷贝,也不是指向m 的指针,其实n 就是m 它自己。
引用的一些规则如下(1)引用被创建的同时必须被初始化(指针则可以在任何时候被初始化)。
(2)不能有NULL 引用,引用必须与合法的存储单元关联(指针则可以是NULL)。
(3)一旦引用被初始化,就不能改变引用的关系(指针则可以随时改变所指的对象)。
以下示例程序中,k 被初始化为i 的引用。
语句k = j 并不能将k 修改成为j 的引用,只是把k 的值改变成为6.由于k 是i 的引用,所以i 的值也变成了6.int i = 5;int j = 6;int &k = i;k = j;// k 和i 的值都变成了6;上面的程序看起来象在玩文字游戏,没有体现出引用的价值。
引用和指针的概念、用法、区别等等引用是对变量去一个别名,这个别名不占内存空间,操作别名可以实现对变量的操作。
指针是一个特殊的变量,它里边存的是某个变量、数组、函数等的地址。
一个指针需要知道,指针的类型,指针所指的类型、指针的值和指针所指的内存区,指针本身所占的内存区。
引用主要用于函数的参数和返回值的传递主要有三种:值传递、指针传递、引用传递。
(1):值传递#include<stdio.h>void fun(int m,int n);int main(void){int a = 1;int b = 2;fun(a,b);printf("%d,%d",a,b);return 0;}void fun(int m,int n){m = m^n; //值传递不会改变原本参数(a,b)的值,只是交换了m,n = m^n; ,n的值,输出的结果仍是1,2m = m^n;}(2):指针传递#include<stdio.h>void fun(int *m,int *n);int main(void){int a = 1;int b = 2;fun(&a,&b);printf("%d,%d",a,b); //指针传递相当于用纸真来操作a,b的值,来return 0;} 达到a,b的交换,输出结果为2,1void fun(int *m,int *n){*m = *m^*n;*n = *m^*n;*m = *m^*n;}(3):引用传递#include<stdio.h>void fun(int &m,int &n);int main(void){int a = 1;int b = 2;fun(a,b);printf("%d,%d",a,b); //引用传递相当于给变量起了个别名,然后用return 0;} 别名来对变量进行操作。