3.3 指针类型
本节主要介绍了:什么是指针、怎么创建指针(空指针、解指针)、指针变量的赋值(空类型指针),提到了指向指针的指针。本片博客还给出了本节的课后习题及其答案,以便讨论交流。
什么是指针
指针是一种存储相关类型变量地址的变量,通常由“*”和相关类型组成,比如 * int、* string等。指针主要用来建立特定结构(如:链表、树)、管理在程序的执行过程中动态分配的对象、传递数组或大型的类对象等。
怎么创建指针
创建指针时由 指针标识符“*”和指针类型组成。同时创建多个指针变量时每个指针前面的“*”符号不能省略,还需要对每个指针变量赋初值。
int *pi = &ival;
int *pi = &ival, *pi2 = &ival2;
野指针
如果创建指针时没有对指针变量进行初始化,就存在指针指向不明的隐患,这种未明确指向的指针一般称为野指针。使用野指针可能会导致程序崩溃、数据损坏、代码出现未定义行为等问题。
int *pi; //此时pi便是一个野指针
pi = &ival; //(假设ival已经在前文定义)此时pi不再是野指针
空指针
当一个指针直指向空地址时即为空指针,空指针虽然不会像野指针一样在使用时导致代码出现问题,但无法对其进行解指针
int *pi = NULL; //此时pi为空指针
*pi = ival; //代码会报错,无法对空指针进行解指针
解指针
指针往往指向内存地址,解指针就是将指针指向的内存地址存储的数据显式的展示出来。
int ival = 1024;
int *pi = &ival;
cout << *pi; //输出可得1024
cout << pi //输出可得ival的存储地址
指针变量的赋值
变量无法赋给不同类型的指针。指针变量有着多种不同的赋值方式,且相互之间容易混淆,故要明确区分“赋值”和“赋地址”
int ival = 1024, ival2 = 2048;
int *pi = &ival, *pi2 = NULL;
//将pi的地址赋给pi2
pi2 = pi; //此时,pi2与pi同时指向ival,*pi与*pi2的值同为1024
//将ival2的值赋给pi2
*pi2 = ival2; //此时,*pi2、*pi与ival的值都被改为1024
//将ival2的地址赋给pi2
pi2 = &ival2; //此时,pi2与ival2的地址相同
//给ival赋值1024
ival = 1024; //此时,*pi与ival的值同为1024,而pi2的值不发生改变
char ch = 'c';
char *pc = &ch;
pc = pi; //错误,char*无法接收int*
空类型指针
空类型指针可以存储不同类型指针的地址,但是无法进行解指针操作,仅获得地址进行比较、查看等操作时,可以使用空类型指针。
void *pvi = NULL, *pvc = NULL; //此时pv指向为空
pvi = pi; //可以进行赋值
pvc = pc; //可以进行赋值
pvi == pvc; //正确,可以进行判等、大、小操作
pi == pc; //错误,不能进行判等、大、小操作
指向指针的指针
指针可以理解为指向某一类变量地址的变量,那指向指针变量地址的变量即为指向指针的指针。
int ival = 1024;
int *pi = &ival;
int **ppi = π
cout << ival << *pi << **ppi << endl; //其结果均为1024
cout << &ival << pi << *ppi << endl; //三者地址相同
cout << &pi << ppi << endl; //两者地址相同
课后
练习
练习3.8:
已知下列定义
int ival = 1024, ival2 = 2048;
int *pi = &ival, *pi2 = &ival2, **ppi = 0;
说明下列赋值将产生什么后果?哪些是错误的?
(a) ival = *pi3; (e) pi = *pi3;
(b) *pi2 = *pi3; (f) ival = *pi;
(c) ival = pi2; (g) pi = ival;
(d) pi2 = *pi; (h) pi3 = &pi2;
参考答案
(a) 错误,int*无法给int赋值
(b) 错误,int*无法给int赋值
(c) 错误,int*无法给int赋值(应改为ival = *pi2)
(d) 错误,int无法给int*赋值
(e) 错误,*pi3为空指针(执行f后e正确)
(f) 正确,ival = 1024
(g) 错误,int无法给int*赋值
(h) 正确。