前言
对于初学者来说,指针是非常晦涩难懂的一部分,可以毫不夸张地讲,如果对于指针能够正确理解,那么基本上对于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(指针)实际是指针所占用得空间
总结:
在理解参数传递时,首先要了解函数调用所执行了什么过程,机器语言做了什么,同时也要了解形参与实参的不同,就很好理了,引用和指针的区别往往作为一道面试和学校的考试题目,由此整理一下,希望对大家有所帮助。