基础面试题:引用和指针的区别

文章目录


前言

对于初学者来说,指针是非常晦涩难懂的一部分,可以毫不夸张地讲,如果对于指针能够正确理解,那么基本上对于C++或C语言的基础理解的了一大半,其他内容相对简单易懂。与指针类似的引用类型对于初学者来说也不是很友好,这里就对指针和引用类型以及它们的区别作一个阐述。

特别提醒:

        在C或C++中,指针和引用类型的区别是什么往往作为一道面试题


一、什么是指针?

指针:

        指针是实现了对其他对象的间接访问复合类型,它指向访问对象(基础类型:整型、浮点等,类对象)的地址。可以对访问对象直接作出访问和操作。简单的理解,指针就是一个访问地址的游标而已;也可以简单理解它是一个int或long类型。它所存放的就是所访问对象的地址。

犹如装地址的盒子,这个盒子的大小永远不会变,固定大小

char* p = "fjdkjfkdjfdjf";
/*
    根据实际编译成32位运用还是64位运用
    如果32位运用length = 4
    如果64位运用length = 8
*/
int basicLength= sizeof(p);

获取对象的地址

例一 (基础类型):指针是指向某个对象的地址

int ival = 100;

int * p = &ival; //取地址,p存放变脸ival的地址,或者说p是指向变量ival指针

例二(类对象):sizeof(类)与sizoef(指针)

class Position{

private int x;

private int y;

public int getX(){

        return x;

}
public int getY(){

        return y;

}
省略...
}

//p1存放一个Position对象的地址
Position* p1 = new Position(); 
/*
    ObjectLength与上个一代码段中basicLength相同,与指针所指向的类型无关
*/
int objectLength = sizeof(p1); 

//注意下面有所不同
int length = sizeof(Position);//它的长度,是Position单个对象所占用内存空间大小

二、引用类型

引用:为对象起的一个别名的复合类型(引用本身并不占用空间)

int ival = 10;

int ival2 = 100;

int &refVal = inval;        //refVal是指向ival(是ival的别名,对refval的操作就如对ival变量的操作)

&refVal = ival2;//报错,引用不能再次引用其他变量

int &refVal;   //报错,引用类型必须被被初始化

int &refVal = 10;//错误,引用必须是一个对象,不能是一个常量

double a = 10.0f;

int &refVal = a; //错误,引用必须是同类型,不能进行类型转换

引用并非对象,相反的,它只是为一个已经存在对象所起的一个另外一个名字


三、指针作为函数参数

如果指针为函数参数,它传递是指向内容的地址的一个副本,在函数内部给它重新赋值,并不能改变函数外边的指针指向,如下:

//如果参数 p1定义为 char* p1 = "name";

void setName(char* p1)

{

        p1 = “new_name"; 

}

char* p1 = "name";

//在函数调用时相当于对于参数进行了一个拷贝,实际操作的是p1副本,并不是p1本身

 函数调用setName(p1)时,p1还是原来的值“name”,而并不是 "new_name".

所以传递的p1与函数内部的p1并不相同

如果不是指针赋值,而是内存拷贝,那情况就不一样了

void setName(char* p1,char* name)

{

        //此处并没做安全检测,假设p1空间是够的,省略...

        strncpy(p1,name,strlen(name));

}

setName(p1,"new_name");//虽然同样对参数进行了拷贝,但是地址新的p1指向的地址还是原来的地址,所以对于指向地址内容的修改同样是生效的,也就是说,新的p1与原来的p1虽然不是同一个,只是名字相同罢了,但是指向地址是一样的,所以对于地址所指向的内容修改是有效的,p1 的新值是 "new_name";


四、引用作为函数参数

因为引用是别名,并没有进行副本操作,它告诉解析器,实际调用的时候,参数并不会进行副本生成,也就是操作的就是真身,而不是副本

void setAge(int &age,int value)

{

        age = value;

}

//如下

int age = 100;

setAge(age,10);//age因为是别名,操作的是age变量本身,所有age的结果值为10


五、引用和指针的区别是什么

          1、引用是别名,本身并不占用空间;指针是对象,这个对象是指向某一块内存的地址,所占用空间大小固定,指针所占空间大小依据编译成32还是64位而定,32位地址是4个字节,64位是8个字节

         2、引用必须在定义的时候就初始化,指针并不需要(但是定义指针时不赋值往往不安全,虽然可以这么做,养成好的习惯是一个好的程序员的修养)

         3、作为函数参数,引用是操作传进变量本身,而指针是传进去的所指向原来地址的副本

         4、引用一旦初始化,别名引用不能再次改变,即:不能再次引用。指针没有这个限制,可以重新指向

        5、如果对引用能够自加或自减,实际是对引用实体进行值的改变,指针是对地址的偏移

        6、存在多级指针,但没有多级引用

        7、因为指针操作时内存地址,引用比指针使用起来相对安全。

        8、sizeof()含义不同,sizoef(引用)是实体占用空间的大小,sizeof(指针)实际是指针所占用得空间


总结:

        在理解参数传递时,首先要了解函数调用所执行了什么过程,机器语言做了什么,同时也要了解形参与实参的不同,就很好理了,引用和指针的区别往往作为一道面试和学校的考试题目,由此整理一下,希望对大家有所帮助。


猜你喜欢

转载自blog.csdn.net/lejian/article/details/128823425