这一篇章主要简单说一下指针。当然只是初步了解,不深入进行研究。
1.什么是指针。
要理解指针,首先得理解内存的存储是把一整块内存分为若干个小的单元,每个单元的大小都是一个字节,而每个字节都有其对应的地址编号。这些地址就是指针,而我们口语中说的指针通常指的是指针变量。以代码举例:
在这个代码中,他的执行逻辑大概是,首先腾出一片内存区域,把它命名为a,而这块内存所存储的内容就是10。随后在取a的地址,并把a的地址放入一块名为b的内存区域,然后再运用解引用符号*取出地址,这样*b所指向的就是a这块区域了。因此,* b其实就是a,给* b赋值也就等于给a赋值。
2.指针类型。
在上面的代码中可以看到,指针是有类型的。如上面代码中的int整型,既然有整型那肯定也有字符char类型等其他类型。那问题来了,二者有何区别呢?仍然以代码来举例:
这个代码的运行会发出警告,因为在定义变量的时候是定义的整型,而却又定义了一个char类型的指针。将代码地址打出来,能发现pa+1,地址加了4,而pb + 1 ,地址只加了1。从这里就可以得出结论:指针的类型决定了指针在被解引用的时候访问的权限。如果是整形指针,就是四个字节,字符指针类型就是一个字节。同时,指针类型也决定其向前或向后能走多大的距离。
3.指针+-整数。
这个其实在前文中已经有所提及,指针加减整数其实就是对地址的加减。也就是说指针加或者减意味着指针的移动,其所对应的地址的存储内容自然而然也会发生变化。而具体移动多少的距离就跟指针本身的类型有关系。
4.野指针。
即指针所指向的位置是不可知的,随机的,不正确的,没有限制的。其成因主要有三,分别为:
指针未初始化:
这个代码中的指针就是未初始化,那么他的值就是随机的不确定的。若需要指针但又不需要将其初始化可定义一个空指针,即int * p = NULL。
指针越界访问:
指针的越界访问与数组的越界访问有着相似之处。就如图中代码所示,不过要注意只有当其超出指向的数组范围时,才会成为野指针。
指针指向的空间释放:
这个代码可以运行,但是不提倡,因为a的地址在函数外已经被释放了,即使在将其赋值为100,也不会成功。
5.指针的关系运算。
注意这样的代码,虽然在大部分编译器中都能实现,但其也是不提倡的。因为标准规定:允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。
6.指针- 指针。
指针与指针相减,实际上得到指针之间元素个数的绝对值,当然前提是两指针指向同一个空间。
7.指针和数组
在前文对指针和数组已经有过提及。简单来说,指针+一个整数可以访问数组中的多个元素:
8.二级指针。
也是类似于套娃的结构,地址会存储在内存中,那么其本身存储的空间肯定也存在一个地址,因此就有了二级指针:
9.指针数组。
把所有地址存在一个数组中,就是指针数组。对指针数组进行访问可以达到二维数组的效果:
遗留问题:
1.迭代和递归我还是不明白。
2.这个代码的循环条件,我不是很理解。
3.指针数组中的运行逻辑还需要再思考一下。
----------------------------------最后编辑于2023.3.4下午五点左右