目录
1.什么是指针?
指针理解的 2 个要点:1. 指针是内存中一个最小单元的编号,也就是地址2. 平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量
总结:指针就是地址,口语中说的指针通常指的是指针变量
- 一个小的单元到底是多大?(1个字节)
- 如何编址?
00000000 00000000 00000000 0000000000000000 00000000 00000000 00000001...11111111 11111111 11111111 11111111
- 在32位的机器上,地址是32个0或者1组成二进制序列,那地址就得用4个字节的空间来存储,所以
- 一个指针变量的大小就应该是4个字节。
- 指针变量是用来存放地址的,地址是唯一标示一个内存单元的。
- 指针的大小在32位平台是4个字节,在64位平台是8个字节。
2. 指针和指针类型
不管是什么类型的指针,大小都是4个字节(x86环境)。但是在x64环境下为8个字节。
刚开始是44 33 22 11再按F10调试:
结果都变成00 00 00 00
刚开始是44 33 22 11(这里int a 和char*不同类型会小报个警告,先不管他)
再继续调试:
结果变成了00 33 22 11和刚刚的int类型不一样这就是区别。
当是int的时候直接改了4个字节,当时char的时候只改了1个字节
所以:指针类型决定了在解引用指针的时候能访问几个字节
第二个意义:
——>指针类型决定了,指针进行+1 、 -1的时候,一步走多远
比如: char* 的指针解引用就只能访问一个字节,而 int* 的指针的解引用就能访问四个字节。
为什么会这样?因为pa认为它指向的是一个整型,所以当给pa加上1的时候就是说我访问完了这个整型就要跳到下一个整型,所以就跳了一个整型
但是对于char来说加上1就是跳过一个字符就是一个字节嘛,所以加了个1。
等价图:
所以:指针类型决定了,指针进行+1 、 -1的时候,一步走多远
总结:
指针的类型决定了,对指针解引用的时候有多大的权限。(能操作几个字节)
问:学这些有什么用??
现在放了10个0 ,现在我想把它们初始化到1—10
用指针依次访问元素,我当我对它解引用操作的时候访问正好一个整型,访问下一个必须要跳一步,我对它解引用的时候想访问4个字节,所以用整型指针是最合适的。
*p解引用操作一次访问4个字节(一个整型元素) p++ 加1操作 | 跳过一个整型,所以这里只有int可以胜任
要是改成char:
3.野指针
概念:野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)
3.1野指针的成因
1.指针未初始化
这里的p没有初始化就随机选了个地址,就会造成非法访问。就比如说你大晚上很困,你回不了家了就随便去陌生人的家里倒头就睡是不是私闯民宅?
2.指针越界访问
如图前10个指针还是正常的,但是这里的循环是到i=12,明显就越界了,越界的那一部分就变成了野指针。
3.指针指向的空间释放(略)
卖关子,放到动态内存开辟的时候再讲。
3.2 如何规避野指针
1.指针初始化
2.小心指针越界
3.指针指向空间释放,及时置NULL
4.避免返回局部变量的地址
5.指针使用之前检查有效性
#include <stdio.h>
int main()
{
int *p = NULL;
//一个指针不知道指向哪里的时候,暂时可以初始化为NULL;
//....
int a = 10;
p = &a;
if(p != NULL)
{
*p = 20;
}
return 0;
}