一、在声明中见到这两个操作符(*和&)时:
①在程序声明变量的时候使用的*,只是表明“它是一个整数,这个整数为某个内存地址,一次访问sizeof(type)长度”。这点不要和(*)操作符混淆;
②在程序声明变量的时候使用的&,只是表明“它是一个引用,这个引用声明时不开辟新空间,它在内存分配表加入新的一行,该行内存地址等于和调用时传入的对应参数内存地址”。 这点不要和(*)声明符,(&)操作符混淆。
引用:(&)
引用就是某一变量(目标)的一个别名,对引用的操作与对变量直接操作完全一样。
引用的声明方法:类型标识符 &引用名=目标变量名;
【例1】:int a; int &ra=a; //定义引用ra,它是变量a的引用,即别名
说明:
(1)&;在此不是求地址运算,而是起标识作用。
(2)类型标识符是指目标变量的类型。
(3)声明引用时,必须同时对其进行初始化。
(4)引用声明完毕后,相当于目标变量名有两个名称,即该目标原名称和引用名,且不能再把该引用名作为其他变量名的别名。
ra=1; 等价于 a=1;
(5)声明一个引用,不是新定义了一个变量,它只表示该引用名是目标变量名的一个别名,它本身不是一种数据类型,因此引用本身不占存储单元,系统也不给引用分配存储单元。故:对引用求地址,就是对目标变量求地址。&ra与&a相等。
(6)可以建立数组的引用。int m[10]={1,2,3,4,5,6,7,8,9,10}; int (&n)[10]=m;
(7)不能建立引用的引用,不能建立指向引用的指针。因为引用不是一种数据类型,所以没有引用的引用,没有引用的指针。
例如:
int n;
int &&r=n;//错误,编译系统把"int &"看成一体——引用,把"&r"看成一体——引用,即建立了引用的引用,引用的对象应当是某种数据类型的变量
int &*p=n; //错误,编译系统把"int &"看成一体——引用,把" *p "看成一体——指针,即建立了指向引用的指针,指针只能指向某种数据类型的变量
(8)值得一提的是,可以建立指针的引用
例如:
int *p;
int *&q=p;//正确,编译系统把" int * "看成一体——指针,把"&q"看成一体——引用,即建立指针p的引用,亦即给指针p起别名q。
引用与指针的区别:
使用引用(reference)和指针(pointer)都可以间接访问另一个值,但它们之间存在两个重要区别:
1.引用总是指向某个确定对象(事实上,引用就是该对象的别名),定义引用时没有进行初始化会出现编译错误;
2.赋值行为上存在差异: 给引用赋值修改的是该引用所关联的对象的值,而不是使该引用与另一个对象关联.引用一经初始化,就始终指向同一个特定对象.
给指针赋值修改的是指针本身,也就是使该指针指向另一对象,指针在不同时刻可指向不同的对象
例:
int ival=1024,ival2=2048;
int *pi=&ival, *pi2=&ival2; //pi指向ival,pi2指向ival2
pi=pi2; //pi此时所指与pi2相同了,即指向ival2了
该赋值操作仅修改了指针pi的值,而pi开始所指向的ival对象值保持不变
对比:
int &ri=ival,&ri2=ival2;
ri=ri2; //assigns ival2 to ival
该赋值操作修改了引用-ri的对象-ival的值,ival的值变成了ival2了,而引用两个本身不变,都还是分别指向原来所关联的对象
二、在声明中见到这两个操作符(*和&)时:
(一)生成左值的解引用操作(*)——得到所指对象
string s("hello world");
string *sp=&s; //sp 指向s,sp的值是s的地址;①sp是一个整数,这个整数指向某个内存地址即s的地址,一次访问sizeof(string)长度
修改指针所指对象的值: *sp="goodbye"; 即此时s的改变了,因为进行了解引用操作(*操作),
修改指针的值:1.string s2="some value";
sp=&s2; //即此时sp 指向s2,而不是s了,sp自身改变了,因为没有使用解引用操作
2.string s2("some value");
string *sp2=&s2; //sp2指向s2
sp=sp2; //此时sp也指向s2了,值变成了s2的地址,同样没有使用解引用操作
区分的重要方法是: 如果对左操作数进行解引用,则修改的是指针所指对象的值;
如果没有使用解引用操作,则修改的是指针本身的值.
(二)取址符(&)——得到自身的地址
我们假设有这么两段内存地址空间,他们取值如下:(单位:H,16 进制)
(假设开辟空间时p 被分配给了3001H、3002H 两个位置)
int *p;
p=2003H; //则p指向了2003H处,值为30 00
*p=3000H //p所指向的对象的值变为3000H
----------------------------------------------------
1.**p的值为多少?
**p=*(*(p))=*(*(2003H))=*(3000H)=0300H。
故**p即为3000H所指向的对象,值为03 00
2.&&p的值为多少?
&&p=&(&(p))=&(3001H),&p为获得p的地址即我们前面假设的3001H。再对3001H取址,此时出错了,
3001H 是个常数怎么可能有地址呢? !!!
3.*&p的值为多少?
*&p=*(&(p))=*(3001H)=2003H,也就是*&p=p。//*(3001H)得到3001H所指对象即20 03——注意,它得到的不是自身哦,有变化
4.&*p的值为多少?
&*p=&(*(p))=&(3000H),读者可能以为&*p=p, 此时出错了,同样的3000H 是个常数怎么可能有地址呢?