【C语言】指针基础 纯干货,一篇文章带你了解指针运算,指针数组,二级指针,野指针

什么是指针?

指针就是地址,也就是一个编号。int * pa的意思是,pa是一个指针变量,用来专门存放地址。他指向的是一个int类型的变量。而我们平常口头所说的指针,其实一般指的是指针变量。也就是说虽然pa里面存放的才是一个地址,或者说一个指针,但是我们平常并不是说pa里面存了一个指针,而是说pa是一个指针。这是口头上的习惯。也就说平常口头所说的指针是指针变量,而真正的指针是指针变量里面存放的内容。这个内容当然也就是一个地址(指针)。

指针变量的大小

要知道指针的大小,首先应该知道地址编号是如何产生的,对于32位的机器来说,有32根地址线,每根地址线可以是高电平也可以是低电平,对应的就是二进制的1和0,这样就可以产生2的32次方个数,这些数就可以用来作为地址编号,而要表示这32位二进制数,需要4个字节大小的空间,因此在32位机器上,指针的大小就是4个字节,同理在64位机器上就能产生2的64次方个数,也就是从64个0到64个1的数字,因此在64位机器上指针大小就是8个字节。

指针的类型

前面我们说了指针的大小在32位机器上都是4个字节,那不什么类型的变量,我只要给他分配四个字节大小的空间,就能够存放他的地址,但是C语言中并没有这么做,而是对于不同类型的变量,规定了不同类型的指针,说明指针类型是有一定意义的。最常见的就是int*类型的指针可以一次性修改四个字节,而char*类型的指针一次性只能修改一个字节。也就是说指针类型可以决定指针解引用的时候最多访问多少个字节。

【C语言】指针基础 纯干货,一篇文章带你了解指针运算,指针数组,二级指针,野指针_第1张图片

通过打印结果可以看出,int*类型的指针+1直接变化了4个字节,而char*类型的指针+1只变化了1个字节。也就是说指针类型决定了指针+1操作时候的步长。

野指针

造成野指针的几种情况

1.指针未初始化

2.在调用函数时创建变量而开辟的内存空间,在函数调用结束之后就会销毁,如果仍然要用这个变量的地址,那就会产生野指针。

3.申请的空间被释放掉

如何避免野指针?

注:把指针初始化成NULL表示指针不指向任何有效空间,并且不能直接使用

1.初始化指针,如果不知道初始化为什么,就初始化为NULL,要使用NULL,要提前引上头文件stdlib.h

2.小心指针越界

3.指针指向空间释放,及时置NULL

4.避免返回局部变量的地址

5.指针使用之前检查有效性(检查指针是否为NULL)

指针运算

1.指针加减整数

指针+1表示指针走一步,至于走一步是走过了多少个字节,取决于指针变量的类型

2.int*p=arr;

arr[i]表示访问数组arr中下标为i的元素,*(p+i)也是访问数组arr中下标为i的元素,因此arr[i]等价于*(p+i),这在理解多次解引用的情况中非常有帮助。

3.指针-指针

指针-指针结果的绝对值是二者之间元素的个数

【C语言】指针基础 纯干货,一篇文章带你了解指针运算,指针数组,二级指针,野指针_第2张图片

从arr[0]地址到arr[9]地址共有9个元素,因此打印结果为9

如果是打印&arr[0]-&arr[9],结果就是-9。

注:指针和指针能够相减的前提是他们指向了同一块内存空间

这为我们提供了一种模拟实现strlen函数的新思路

【C语言】指针基础 纯干货,一篇文章带你了解指针运算,指针数组,二级指针,野指针_第3张图片

只要找到末尾元素也即\0和首元素的指针即可。

4.指针可以比较大小,但是C语言标准规定,允许指向数组元素的指针与指向数组最后一个元素后面那个内存位置的指针进行比较,但是不允许与指向数组首元素前面那个内存位置的指针进行比较。

指针和数组的关系

数组名就是数组首元素地址,也就是一个指针,又因为数组中的元素是连续存放的,因此通过数组名就可以遍历访问整个数组。

二级指针

指针变量也是变量,也要在内存上开辟空间,因此也有地址,当然也可以通过这个地址找到这个指针变量,如果我们把这个一级指针的地址放到另一个指针变量里面,那么这个存放一级指针地址的变量就是二级指针变量。举个例子

【C语言】指针基础 纯干货,一篇文章带你了解指针运算,指针数组,二级指针,野指针_第4张图片

p是一个指针变量,*代表他是一个指针,int代表他指向的变量类型是int,pp也是一个指针变量,*代表他是一个指针,int *代表他指向的变量类型是int*,因此我们把pp称为二级指针变量。

指针数组

即用来存放指针的数组。下面是通过指针数组打印数组中元素的例子

【C语言】指针基础 纯干货,一篇文章带你了解指针运算,指针数组,二级指针,野指针_第5张图片

arr[i][j]看起来像一个二维数组,但其实不是,因为二维数组在内存中是连续存放的,但是arr[i][j]当i变化的时候并不是连续存放的。

如果是打印字符数组,直接以%s的形式打印即可

【C语言】指针基础 纯干货,一篇文章带你了解指针运算,指针数组,二级指针,野指针_第6张图片

你可能感兴趣的:(c语言,开发语言,算法,c++)