指针
一、指针是指向另外一种类型的复合类型。
二、指针和引用区别
1、指针本身就是一个对象,允许对指针赋值和拷贝,而且指针的生命周期内它可以先后指向几个不同的对象。
2、指针无须在定义时赋初值,和其他内置类型一样,在块作用域内定义的指针如果没有初始化,也将拥有一个不确定的值.
3、引用本身并非一个对象,没有实际地址,一旦定义了引用,就无法令其再绑定到另外的对象,之后每次使用整个引用都是访问它最初绑定的那个对象,指针和它存放的地址之间就没有这个限制。不能定义指向引用的指针。
三、指针存放某个对象的地址,要获取该地址,需要使用取地址符(&)。
四、如果指针指向了一个对象,则允许使用解引用符(*)来访问对象
五、对指针解引用会得到所指向的对象,因此如果给解引用的结果赋值,实际上就是给指针指向的对象赋值。
六、指针值应属于下列4种状态之一:
1、指向一个对象
2、指向紧邻对象所占空间的下一个位置
3、空指针,指针没有指向任何对象
4、无效指针
七、空指针不指向任何对象,得到空指针最直接的办法就是用字面值nullptr来初始化指针,也可以通过将指针初始化为字面值0来生成空指针。
八、2个指针存放的地址相同有3种可能:
1、他们都为空
2、都指向同一个对象,或者指向了同一个对象的下一个地址
3、一个指针指向某对象,另一个指针指向另外对象的下一个地址
九、void*是一种特殊的指针类型,可用于存放任意对象的地址,不能直接操作void*指针所指的对象,因为并不知道这个对象是什么类型
十、void*指针通常能做的事:
1、和别的指针比较
2、作为函数的输入或输出
3、赋值给另外的void*指针
int ival = 41;
int* p = &ival; // 指针存放某个对象的地址,要获取该地址,需要使用取址操作符(&)
cout << p << endl; // 0xxxxxx
cout << *p << endl; // 41 如果指针指向了一个对象,则允许使用解引用符(*)来访问该对象
*p = 1;
cout << ival << endl; // 1 对指针解引用会得出所指的对象,因此如果给解引用的结果赋值,实际上就是给指针所指向的对象赋值
cout << *p << endl; // 1
int i = 42;
int& r = i; // &紧随类型名出现,因此是声明的一部分,r是一个引用
cout << r << endl; // 42
int* q; // *紧随类型名出现,因此是声明的一部分,q是一个指针
q = &i; // &出现在表达式中,是一个取地址符
cout << q << endl; // 0xxxxxx
*q = i; // *出现在表达式中,是一个解引用符
cout << *q << endl; // 42
int& r2 = *q; //&是声明的一部分,*是一个引用符
cout << r2 << endl; // 42
int* p1 = nullptr; // 空指针
int* p2 = 0; // 空指针
int j = 43;
int* pj = 0; // pj被初始化,但没有指向任何对象
//cout << *pj << endl; //异常, pj是nullptr
int* pj2 = &j; // pj2被初始化,存有j的地址
cout << *pj2 << endl; // 43
int* pj3; // 如果pj3定义于块内,则pj3的值无法确定
//cout << *pj3 << endl; // 错误,使用了为初始化的局部变量
pj3 = pj2; // pj3和pj2指向同一个对象j
cout << *pj2 << endl; // 43
pj2 = 0;// pj2不指向任何对象
//cout << *pj2 << endl; // 异常, pj2是nullptr