练习2.18
#include <iostream>
using namespace std;
int main() {
//更改指针的值
int ival = 4;
int* p = 0; //pi被初始化,但是没有指向任何对象
p = &ival; //pi的值被改变,现在pi指向了ival
//改变指针所指对象的值
*p = 0; //ival的值被改变,指针pi并没有改变
return 0;
}
练习2.19
- 引用本身并非一个对象,一旦定义了引用,就无法令其再绑定到另外的对象,之后每次使用这个引用都是访问它最初绑定的那个对象。
- 指针本身就是一个对象。和其他变量一样(只要不是引用),给指针赋值就是令它存放一个新的地址,从而指向一个新的对象。
- 在指针的生命周期内,它可以先后指向几个不同的对象。
- 指针无需在定义时赋初值,和其他内置类型一样,在块作用域内定义的指针如果没有初始化,也将拥有一个不确定的值。但建议对指针初始化,如果实在不知道指针指向哪里,把它初始化为0或nullptr。
在C和C++中,指针一般指的是某块内存的地址,通过这个地址,我们可以寻址到这块内存;而引用是一个变量的别名,例如我们给小明起了个外号:明明,那我们说明明的时候,就是说小明。对于指针来说,它是一个地址,这个地址是一个数值,那么就意味这个数值可以为0(空指针),也可以为其他,即指针可以不指向任何东西。而对于引用来说,他是一个外号,外号一定是“某个存在物体”的外号,所以引用不能为空,即不能存在空引用。根据以上可知指针和引用的一个重要不同:指针可以为空,引用不能为空。这就意味着我们拿到一个引用的时候,是不需要判断引用是否为空的,而拿到一个指针的时候,我们则需要判断它是否为空。这点经常在判断函数参数是否有效的时候使用。
作者:nkaifang
链接:https://www.zhihu.com/question/37608201/answer/90293843
来源:知乎
另外,指针可以多次赋值,而引用不可以,引用在一开始初始化的时候,就与该对象绑定。
int a = 0;
int b = 1;
int *point = NULL;
point = &a; // 在某个时刻,指针可以指向a
point = &b; // 换个时刻,指针可以指向b
练习2.20
#include <iostream>
using namespace std;
int main() {
int i = 42;
int* p1 = &i; // p1是一个合法的指针,存放这i的地址
*p1 = *p1 * *p1; //由符号*得到指针p所指的对象,对它们进行相乘,得到的结果经由p为变量i赋值
cout << *p1 << endl;
cout << i << endl;
return 0;
}
练习 2.21
(a)错误,试图把int类对象的地址赋给double型指针。
(b) 错误,不能把int变量直接赋给指针。
(c)合法。
练习2.22
if(p) //取决于p的值是0还是非0,条件的值分别对于0和1
if (*p) //取决于p指针所指的int对象的值是0还是非0
p不等于0,条件为真,结果为True
#include <iostream>
using namespace std;
int main() {
int i = 0;
int * p = &i;
if (p)
{
cout << "True" << endl;
}
return 0;
}
*p等于0,条件为假,结果为不输入任何内容
#include <iostream>
using namespace std;
int main() {
int i = 0;
int * p = &i;
if (*p)
{
cout << "True" << endl;
}
return 0;
}
练习2.23
- 除2种例外情况外,其他所有指针类型都要和它所指向的对象严格匹配。
- 指向对象时,不能把变量直接赋给指针,而是通过取地址符来获取该地址。
练习2.24
void 是一种特殊的指针类型,可用于存放任意对象的地址。
而lp非法的原因是试图把int类对象的地址赋给long型指针。不满足条件:除2种例外情况外,其他所有指针类型都要和它所指向的对象严格匹配。