引用 : 就是为对象起了另一个名字;例 : int i = 42; int &a = i;这里 a是i的另一个名字;
定义引用时,程序把引用和它的初始值绑定在一起,而不是将初始值拷贝给引用;
因为无法令引用重新绑定到另外一个对象,因此引用必须初始化;
引用并非对象,只是为一个已经存在的对象起的另外一个名字;引用只能绑定到对象上,而不能与字面值或某个表达式的计算结果绑定在一起;
指针 : 变量名前一定要有 * ; 获取地址 ,使用& ;
指针的类型 要与所指向对象的类型一致 ;
指针值 : 应属于下列4中状态 之一 :
1 , 指向一个对象;
2, 指向紧邻对象所占空间的下一个位置 ;
3 , 空指针 ,意味着指针没有指向任何对象 ;
4, 无效指针 , 就是上述情况之外的其他值 .
试图拷贝或以其他方式访问无效指针的值都将引发错误 ,编译器不检查此类错误 ;
利用 解引用符(*) 访问对象 ;
空指针 ;不指向任何对象 ;使用指针之前先检查它是否为空 ;
生成空指针的方法 :
int *p = nullptr; //等价于 int * p = 0;
int *p1=0; //直接将p1初始化为字面值常量0;
int *p2 = NULL ;//等价于 int *p2=0; 需要引入 #include cstdlib;
建议初始化所有指针 ;在可能的情况下 ,尽量等定义了对象之后再定义指向它的指针 ;
对于两个类型相同的合法指针,可以 用(==) 或 (!=)来比较,结果为bool类型 ;如果两个指针存放的地址值相同,为true ;
两个指针存放地址值相同 的3中情况 :
1, 都为空 ;
2 ,指向同一个对象 ;
3, 都指向了同一个对象的下一地址 ;
void*是以一种特殊的指针类型,可存放任意对象的地址 ;因为不知道这个对象是什么类型,无法确定在这个对象上做哪些操作,所以不能直接操作void*指针所指的对象 ;
引用不是对象,没有实际地址,所以不能定义指向引用的指针 ;
指针,引用 共同点 : 实现了对其他对象的间接访问 ;
指针 与引用的区别 :
1,指针本身就是对象,允许对指针赋值和拷贝,而且在指针的生命周期内可以先后指向几个不同的对象;
2, 指针无须在定义时赋初值;
指向指针的指针 :
int value = 12; //int 型变量
int *p = &value; // 定义指针p ,值为value的地址
int **p1 = &p; //定义指针p1, 值为p的地址;
int *p2 = p; //定义指针p2,值为p存储的值;
const限定符 :相当于java中的final ;
const对象一旦创建就不能再改变 ,所以必须初始化;初始值可以使任意复杂的表达式 ;
与非const类型所参与的操作相比 ,主要的区别在于只能在const类型的对象上执行不改变其内容的操作 ;
默认情况下 ,const对象仅在文件内有效 ; 解决办法 : 对const变量,无论是声明还是定义,都添加extern关键字 ;这样只需要定义一次就可以在其他文件访问了;
引用的类型必须与其引用对象的类型一致 ,例外情况之一 :
在初始化常量引用时,允许用任意表达式作为初始值,只要该表达式的结果能转成引用的类型即可;尤其允许一个常量引用绑定非常量的对象,字面值,甚至是一般表达式 ;
例 : int i = 42;
const int &r = i ;//允许const int &绑定到一个普通int对象上;
const int &r1 =42; //r1是一个常量引用 ;
const int &r2 = r*2;//
int & j = r * 2; / /错误 :j是一个普通非常量引用 ;
指针和const :
指向常量的指针 : 不能用指针改变所指对象的值 ; 存放常量对象的地址,只能使用常量指针;
指针类型必须与所指对象类型一致 例外之一 :
允许一个指向常量的指针指向一个非常量对象 ;
例 : const double i = 3.14;
const double *p = &i;
*p = 2; //错误 ,在这里不能使用指针修改对象的值;
double d = 3.245;
p = &d ; //正确 ;这是例外情况之一;
常量 指针 : 使用const可以修饰任意对象,包括指针;
必须初始化 ,初始化完成,它的值(存放在指针中的地址)就不能再修改了.不变的是指针本身的地址值而不是地址所指的值 ;