一,关于指针
1.指针的基础概念
指针是可存储地址的变量,存储在指针中的地址可以是变量或者其他数据的地址。
指针不仅仅是指向某地址,指针还关注指向该地址的数据类型。
例如:long* num_ptr {};
这里的num_ptr指针今后只能存储long类型的变量地址,尝试用它存储非long类型的变量地址将会产生编译报错。
注意,无论指针变量指向什么类型或者大小的数据,指针变量本身的大小是相同的,指针变量的大小仅仅取决于目标平台的可寻址内存的大小。例如,对于64位的计算机架构,指针变量的大小一般是8个字节。
2.指针的定义和使用
a.指针的初始化
未初始化的指针使用起来风险很大,因此,定义指针的同时必须初始化,如果不知道指定什么样的初始值,可以先初始化为nullptr。
因此,下面这段代码:
long* num_ptr {};
应该改为:
long* num_ptr {nullptr};
也可以使用自定义类型来初始化指针:
char16_t* char_ptr {nullptr};
b.指针的具体使用
(1)指针赋值
对指针变量使用操作符"="会改变指针的指向,所以,对指针采取赋值操作可以理解为指针方向的重定向。
例如,如果p1和p2是两个指针变量,"p2=p1"操作会让p2去指向p1当前正在指向的内存地址。
(2)指针的算术运算
算术运算的本质是让指针沿着一定的方向去移动指定大小的单位。
拿指针的加法运算举例,整数会先和指针所指向的类型大小(单位是字节)相乘,得到偏移量,然后指针的初始地址按照这个偏移量往前移动一定的单位。
3.地址运算符&
地址运算符"&"可以获取变量的内存地址,常用于指针变量的初始化。
&可以应用在任何类型的变量上面,然后用变量对应的指针类型去存储变量的地址。
例如要获得int类型变量的地址,则存储地址的指针必须也是int类型。
int num=10;
int* p_num=#
auto p_num=# //也可以让编译器判断类型
auto* p_num=# //auto*,让代码更清晰
4.解引用运算符*
间接运算符"*"可以获取内存地址所存储的对应的变量值。
因为"*"是通过内存地址来间接获取变量的值,所以称为间接运算符,通常也称它为解引用运算符。
符号"*"有时候是用来声明指针的,有时候是用来解引用的。
当它和类型放在一起,例如"int*",便是声明指针的;
当它和变量放在一起(前面没有加类型或者auto),例如"*p_value",便是解引用的。
下面这段处理逻辑相当于:"data_2 = data_1"。
ptr = &data_1;
data_2 = *ptr;
5.char类型与指针
代码样例: </