内存中每个单元都有编号,编号又被成为地址,也叫作指针。平常说的指针,指的是指针变量,是用来存放内存地址的变量。
指针变量就是用来存放地址。
在32位的机器上,地址是32个0或者1组成二进制序列,那地址就得用4个字节的空间来存储,所以
一个指针变量的大小就应该是4个字节。
那如果在64位机器上,如果有64个地址线,那一个指针变量的大小是8个字节,才能存放一个地
址。
指针类型决定了,指针进行解引用操作时访问几个字节(权限)cahr*的指针解引用访问1个字节,int*的指针解引用访问4个字节,double*的指针,解引用访问8个字节
指针类型决定了指针的步长(向前/向后 走一步都多大的距离),int*指针+1的意思是跳过一个整形,也就是向后走4个字节,char*指针+1,意思是跳过一个字节,也就是向后走一个字节,double*的指针+1,意思是跳过一个double,也就是向后走八个字节,short*指针+1,实际上是向后走两个字节
野指针,一个指针没有明确的指向,指向位置是不可知的(随机的、不正确的、没有明确限制的)
指针未初始化
指针越界
指针指向的空间释放,指向的不属于当前程序
如何避免空指针
1. 指针初始化
2. 小心指针越界
3. 指针指向空间释放,及时置NULL(本质是0,就是用来初始化指针,并且是不能访问的)
4. 避免返回局部变量的地址,避免返回栈空间的地址
5. 指针使用之前检查有效性
向前越界
下图是上图的一个优化但是随之而来还有一个问题就是,向前越界了。实际在绝大部分的编译器上是可以顺利完成任务的,然而我们还是应该避免这样写,因为标准并不保证它可行。
标准规定:
允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与
指向第一个元素之前的那个内存位置的指针进行比较。
指针-指针,计算的是指针之间的元素个数,指针和指针相减之后的绝对值是指针和指针之间的元素个数,两个指针相减的前提是指针指向的是同一块连续的空间。
数组的指针访问
数组和指针不是一种东西,数组能够存放一组数,是连续的该空间,指针是一个变量,是存放地址的,4/8个字节。数组名是地址,地址又称为指针,数组把首元素的地址交给一个指针变量后,可以通过指针来访问数组。
二级指针
a的地址存放在pa中,pa的地址存放在ppa中。pa是一级指针
**ppa 先通过*ppa 找到pa ,然后对pa 进行解引用操作: *pa ,那找到的是a。所以通过个**ppa赋值也就相当于给a赋值。
指针数组
是存放指针的数组,整形数组——存放整形的数组,字符数组——存放字符的数组。
arr是一个数组,有五个元素,每个元素都是一个整形指针。