首页 > 代码库 > 指针和引用

指针和引用

引用:

引用是某个对象(即变量)的别名。

形式如下:

类型 &引用名 = 变量名;

注意:

1.在定义引用时,引用符&在类型与引用名之间的位置是灵活的。

int& ir = i;

int & ir = i;

int &ir = i;

以上几种定义完全相同。

2.在变量声明时出现的&才是引用运算符,其他地方出现的&都是地址操作符。

int& fun( int &i1, int &i2);    //引用参数,函数返回引用。

3.引用代表一个变量的别名,必须在定义时初始化,不能在定义完成后再给它赋值。

float f;

float &fr;

fr = f;

以上语句是错误的。

可为一个变量指定多个引用。为引用提供初始值的,可以是一个变量,也可以是另一个引用名。

4.一个引用名只能是一个变量的别名,不能再次将它指定为其他变量的别名。

5.引用实际是一种隐式指针,但它与指针的用法存在区别。

6.当用&运算符获取一个引用的地址时,实际取出的是引用对应的变量的地址。

int i = 9;

int &ir = i;

int *pi = &ir;

pi实际指向的是i。

7.建立引用时有一些限制

不能建立引用的引用;不能建立引用数组;不能建立数组的引用;可以建立指针的引用,但不能创建指向引用的指针。

int a[10];

int &aa = a;                    //错误,不能建立数组的引用。

int &ia[5];                            //错误,不能建立引用数组。

 

指针:

指针功能最强但又最危险。

指针变量的定义语句:

数据类型 * 变量名;

int * iPtr;

int iCount = 28;

iPtr = &iCount;

(*iPtr的类型是整型,指针iPtr指向该整数,所以iPtr的类型是整型指针,而iPtr的地址(即&iPtr)的类型是整型指针的地址,即指向整型指针的指针。三者都不相同。)

(在32位机器中,整数和指针都占4个字节。但指针和整数表示的是不同的类型。)

指针的初始化:

指针在使用前要进行初始化。指针忘了赋值比整型变量忘了赋值危险得多

 

指针类型与实际存储的匹配:

指针是有类型的,给指针赋值,不但必须是一个地址,而且应该是一个该指针类型相符的变量或常量的地址。

int i=0;

int * iPtr = &i;      // *iPtr的内容是起始点为i的地址的一个整型数。

指针具有一定类型,它是值为地址的变量,该地址是内存中另一个该类型变量的存储位置。

指针运算:

数组名本身,没有方括号和下标,它实际上是地址。表示数组的起始地址。 

int iArray[10];

int * iPtr = iArray;                //用数组名对指针初始化。

或   iPtr = &iArray[0];                  //同样表示数组的第一个元素的地址。

由于指针是具有某个数据类型的地址,所以指针运算都是以数据类型为单位展开的。即 iPtr是个整型指针,iPtr++使指针指向下一个整数。若在32位系统中,iPtr的地址值实际是增加4,因为在32位系统中int型占4个字节。

只有加法和减法可用于指针运算。

sum += *iPtr;

iPtr++;

以上两条语句可压缩为以下一条语句:

sum += *iPtr++;     或 sum += *(iPtr++);

指针和数组:

数组名可以拿来初始化指针,数组名就是数组第一个元素地址。

数组名是指针常量,区别于指针变量。给数组名赋值是错误的。

int iArray[100];

int sum = 0;

……

for(int i = 0; i < 100; i++)

{

  sum += *iArray;

  iArray++;                          //Error。数组名不是左值。

}

数组名表示内存中分配了数组的固定位置,修改了这个数组名,就会丢失数组空间。

 

const指针:

指向常量的指针(常量指针)

在指针定义语句的类型前加const,表示指向的对象是常量。

const int a = 78;

const int b = 28;

const int * pi = &a;

* pi = 58;    //Error。

pi = &b;      //OK.

int * pj = &b; //error。b为常量。不能把它的地址赋给非常量指针。

常量指针定义const int * pi = &a;告诉编译器,*pi是常量,不能将*pi作为左值进行操作。

指针常量

在指针定义语句的指针名前加const,表示指针本身是常量。

char * const pc = "asdf";

pc = "dfgh";   //Error.指针常量不能改变其指针的值。

*pc = ‘b‘;  //OK.

*pc++ = ‘y‘;  //Error. 指针常量不能改变其指针的值。

在定义指针常量时必须进行初始化。

指针常量定义 int * const pc = &b;告诉编译器,pc为常量,不能作为左值进行操作,但是允许修改间接访问值,即*pc可以修改。

常量指针常量

可以定义一个指向常量的指针常量,它必须在定义时进行初始化。

const int ci = 7;

int ai;

const int * const cpc = &ci;

const int * const cpi = &ai;

*cpi = 39;   //Error

ai = 39;   //OK.

常量指针常量 const int * const cpc = &b;告诉编译器,cpc和*cpc都是常量,它们都不能作为左值进行操作。

总结:若const位于*号左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;若const位于*号右侧,const就是修饰指针本身,即指针本身是常量。

 

指针和引用