引用
1.int ival=1024; int &refval=ival;
2.引用(reference)既别名。
3.引用无法重新绑定到另一个对象身上。
4.引用必须初始化。
5.引用并非对象。
6.操作引用等同操作其绑定的对象。
7.由于引用不是对象,所以引用本身没有引用。
8.允许在一条语句中定义多个引用.
int i=47,i2=74, &r1=i;
int &r2=i, &r3=i2;
9.引用只能绑定在对象上,不能与字面值或表达式的计算结果绑定在一起。
指针
1.指针(pointer)是“指向(point to)”另外一种类型的复合类型。
2.与引用类似,指针也实现了对其他对象的间接访问。
3.指针本身就是一个对象可以对指针赋值和拷贝。
4.指针在自身生命周期内可以先后指向不同的对象。
5.指针不强制在定义时赋初始值,在块作用域内未初始化将拥有一个不确定值,但是强烈建议初始化所有指针。
6.指针存放对象的地址,获取对象地址需要使用取地址符(&)
int ival=47;
int *p=&ival; //p是ival的指针,存放ival的地址。
7.不能定义指向引用的指针。
8.指针类型必须和它所指向的对象匹配:
double dval;
double *p=&dval;//初始值是double类型对象的地址。
double *p2=p; //初始值是指向double类型的指针。
9.指针值(地址)4种状态:
①.指向一个对象。
②.指向紧邻对象所占空间的下一个位置。
③.空指针,不指向任何对象。
④.无效指针,上述情况之外的值。
10.利用指针访问对象,可用解引用符(*)访问对象:
int ival=47;
int *p=&ival;
std::cout << *p << std::endl; //输出47
11.也可用*p为对象ival赋值:
int ival=47;
int *p=&ival;
std::cout << ival << std::endl; //输出47
std::cout << *p << std::endl; //输出47
*p=74;
std::cout << ival << std::endl; //输出74
std::cout << *p << std::endl; //输出74
12.空指针(null pointer)不指向任何对象:
int *p1=nullptr; //等价于int *p1=0;
int *p2=0;//等价于int *p2=NULL(NULL是预处理变量,需要cstdlib头文件);
13.不能把int变量直接赋给指针,int变量的值等于0也不行。
int ival=47;
int *p=&ival;
int zval=0;
p=zval; //错误,不能将int类型变量的值分配到int * 类型的对象实例。
14.给指针赋值就是让指针指向新对象,存放新地址。
15.赋值语句改变的永远是等号左边的对象。
#include <iostream>
int main() {
int ival = 47;
int *p = &ival;
std::cout << *p << std::endl; //输出47
int zval = 74;
p = &zval;
std::cout << *p << std::endl;//输出74
return 0;
}
16.指针可以用在条件表达式中,非0指针条件值都是true:
int ival = 47;
int *p = 0;//空指针
int *p2 = &ival;
if (p) {
std::cout << *p << std::endl;//p的值是0,条件为false,跳过无输出
}
if (p2) {
std::cout << *p2 << std::endl;
}//p2的值不是0,条件为true,输出47
17.判断两个指针是否相等(==):两个空指针(相等)、指向同一个对象(相等)、指向同一个对象的下一个地址(相等)。一个指针指向一个对象,另一个指针指向另一个对象的下一个地址,两个指针也有可能相等(指针相等)。
18.void * 可存放任何对象的地址,但是地址中是什么类型的对象却不得而知,不能直接操作void *指针所指的对象。
int obj = 47, *p = &obj;
void *pv = &obj;
pv = p; //pv可存放任意类型指针
int obj1 = 74;
*pv = obj1; //E0852 表达式必须是指向完整对象类型的指针
std::cout << pv << std::endl;
std::cout << *pv << std::endl; //E0852 表达式必须是指向完整对象类型的指针