Blog

Keep up to date with the latest news

C语言·深入理解指针 (初阶)

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 指针和指针类型:我们都知道,变量又不同的类型,那么,指针有没有类型呢?

准确的说:是有的。

我们都知道,指针变量是用来存放地址的,指针所指向的对象的类型不同,这指针变量的类型不同。

例如:

代码语言:javascript代码运行次数:0运行复制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:感谢大家的观看,后续的深入理解指针(进阶)将会在不久后发布。