pi = &ival ;//pi的值被改变,现在pi指向了ival;
*pi = 0; //ival的值被改变,指针pi并没有改变,也就是说指针地址没有变,pi存的是对象的地址
任何非0指针对应的条件值都是True。
指针和引用的区别:
指针和引用都能提供对其他对象的间接访问,然而在具体实现细节上二者有很大不同,其中最重要的一点就是引用本身并非一个对象。一旦定义了引用,就无法令其再绑定到其他的对象,之后再次使用这个引用都是访问它最初绑定的对象。
指针和它存放的地址之间就没有这种限制了。和其他任何变量(只要不是引用)一样,给指针赋值就是令它存放一个新的地址,从而指向一个新的对象。
解引用符(*)、取地址符(&)、类型修饰符(*或&)
int *p1, *p2; //将修饰符*和变量标识符p1、p2写在一起; int* p1; //将修饰符*和类型名int卸载一起;
声明符是指定对象或函数名称的声明的组成部分
在同一条定义语句中,虽然基本数据类型只有一个,但是声明符的形式却可以不同。
int *p中int是基本数据类型,*是类型修饰符(解引用符),类型修饰符是声明符的一部分,p是变量标识符。
int i =42; int *p; //p是一个int型指针 int *&r = p; //r是一个对指针p的引用 PS:&r 是指向p的地址的指针,r是对指针p的引用 r = &i; //r引用了一个指针,因此给r赋值&i就是令p指向i int *p = &i; *r = 0 ; //解引用r得到i,也就是p指向的对象,将i的值改为0;
小结:
1.指针与引用的含义
int *p;
一个指针给出来,就包括了2样东西,指针指向的地址p ,指针自己的地址 &p,
int &p1=p;
引用就是变量的别名!p1初始化后,使用p1就是使用p本身
2.const 常量指针
const int *p,int *const p,const int *const p
这三者的不同,第一个指向常量的指针,第二个常量指针,第三个是一个指向常量的常量指针,这三者的区别是:第一个存储的指针可以更改,指针指向的值不能更改,第二个存储的指针不能更改,指针指向的值可以更改;第三个就是两者都不能更改;
代码描述:
int a=5;
int b=6;
const int *p1=&a;
*p1=1;报错,值不能改
p1=&b;可以,地址可以改
int * const p2=&a;
*p2=1;可以
p2=&b报错
const int *const p3=&a;
*p3=1;报道
p3=&b;报错
现在回到问题:
int * p = new int(1);
const int &p3 = p; 错误
分析: const int *& 这是一个引用,引用的是什么? const int * ,就是一个指向常量的指针
再来看 int *p 是什么 ,这是一个指向变量的指针
这样看就清晰了,一个是指向变量的指针,一个是指向常量的指针,在引用初始化看来,根本就是两种生物了!理所应当初始化失败!
所以const int *& 初始化 就要const int * 类型!
一个指针 被引用 ,不光指针的指向,指针自己的地址也被引用了!
小结:
非常量可以转换成常量,而常量不能转换成非常量。
普通的 int & 不能绑定到 int 常量上:
const int ci = 42; int &r = ci ;//错误
const int &可以绑定到一个普通 int 上:
int i = 0; const int &r2 =i;//正确,const int&可以绑定到一个普通 int 上 ;常量int引用。
引用 = 绑定:
int i = 42; int &r1 =i ;//引用 r1绑定对象 i
关于顶层const和底层const:能改变变量标识符的值 是底层const,不能改变变量标识符的值 是顶层const;
int i = 0; int *const p1 = &i; //不能改变p1的值,这是一个顶层const; const int ci =42 ; //不能改变ci的值,这是一个顶层const; const int *p2 = &ci; //允许改变p2的值,这是一个底层const;
整数的地址就是指向整数的指针:
auto = &i; //d是一个整型指针(整数的地址就是指向整数的指针)
对常量对象取地址是一种底层const:
const int ci = i; auto e = &ci; //e是一个指向整数常量的指针(对常量对象取地址是一种底层const)
const int ci = i; auto &g =ci; //g是一个整型常量引用,绑定到ci auto &h = 42;//错误:不能为非常量引用绑定字面量 const auto &j =42;//正确:可以为常量引用绑定字面量
设置一个类型为auto的引用时,初始值中的顶层常量属性仍然保留。和往常一样,如果我们给初始值绑定一个引用,则此时的常量就不是顶层常量了。
要在一条语句中定义多个变量,切记,符号&和*只从属于某个声明符,而非基本数据类型的一部分,因此初始值必须是同一种类型:
auto k = ci, &l = i;//k是整数,l是整型引用 auto &m = ci, *p = &ci;//m是对整型常量的引用,p是指向整型常量的指针 auto &n = i, *p2 = &ci; //错误:i的类型是int,而&ci的类型是const int
引用&必须初始化。int&必须初始化。