1 何为指针:
简单来说,指针就是一个地址,存放的是内存单元编号。
想要理解指针,我们首先要对一下与指针相关的东西有所了解。
1.1 地址总线:
在计算机中,我们常用二进制来对数据进行存储,而二进制又由0 / 1组成,在计算机中,我们将高电压表示1,低电压表示0
我们可以简单理解,32位机器有32根地址总线, 每根线只有两态,表⽰0 / 1,那么 ⼀根线,就能表⽰2种含义,2根线就能表⽰4种含义,依次类推。32根地址线,就能表⽰2^32种含 义,每⼀种含义都代表⼀个地址。
我们平时所说的x64和x86分别代表64位地址线和32位地址线。
1.2 指针相关的操作符:
1.2.1 取地址操作符(“ & ”):
该符号的意思就是将使用对象的地址所取出。
例如:
p代表的就是a的地址。
1.2.2 解引用操作符(“ * ”):
该符号的意思就是使对象解引用,解引用对象的地址,使其所指向的对象暴露出来。
例如:
1.3 指针类型的大小:
在C语言中,指针类型的大小是和地址总线有关系的;
如果我们使用的是x64环境,指针类型的大小就是8个字节;
如果我们使用的是x86环境,指针类型的大小就是4个字节;
2 指针和指针类型:
我们都知道,变量又不同的类型,那么,指针有没有类型呢?
准确的说:是有的。
我们都知道,指针变量是用来存放地址的,指针所指向的对象的类型不同,这指针变量的类型不同。
例如:
int a = 0;
int* p = &a;
char b = 'a';
char* pc = &b;
这里可以看到,指针的定义方式是: type + * 。
其实: char* 类型的指针是为了存放 char 类型变量的地址。 short* 类型的指针是为了存放 short 类型变量的地址。 int* 类型的指针是为了存放 int 类型变量的地址。
那么指针的类型有什么用呢?
2.1 指针 + - 整数:
从以上代码我们可以看出:如果是char*类型的指针,指针向前走或者向后走一个字节;
如果是int类型的指针,指针向前走或者向后走四个字节;
2.2 指针的解引用:
又该代码可知,n中存放的是十六进制的0x11223344,在内存中表示为
当我们调试完*pc = 0时我们会发现,n中的数据变成了
继续调试会发现,n中的数据变成了
由此可知:
指针的类型决定了,对指针解引用的时候有多大的权限(能操作几个字节)。
比如: char* 的指针解引用就只能访问一个字节,而 int* 的指针的解引用就能访问四个字节。
3 野指针:
3.1 概念:
野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)
3.2 野指针的成因:
1. 指针未初始化;
2. 指针越界访问;
3. 指针指向的被空间释放;
3.3 如何规避野指针:
1. 指针初始化
2. 小心指针越界
3. 指针指向空间释放,及时置NULL
4. 避免返回局部变量的地址
5. 指针使用之前检查有效性
4.指针的运算:
4.1指针 - 指针:
指针 - 指针 表示的是指针之间的元素的个数;
例如:
因为arr[0] 和arr[8]之间隔了8个元素,并且arr[0]的地址小于arr[8]的地址,所以最终的值为-8.
5 二级指针:
我们知道假设给一个int类型的a变量,则a的地址可以用int*类型的p来储存,那么我们又应该如何来储存p的地址呢,他的类型又是什么?
通过分析之前的指针代码可知:因为a是int类型的变量,所以p的类型就是int*类型的指针
那么同理,我们变量名是pp指针来存放p的地址,由于p的类型是int*,所以pp的类型就
应该是int* *,
也就是int** pp = &p;
这就是我们所说的二级指针。
ps:
感谢大家的观看,后续的深入理解指针(进阶)将会在不久后发布。