重新认识C指针
指针是C语言中的难点,但其本质和其他类型并无不同,下面我们从几个方面来重新认识指针。
在这个过程中,我需要你先抛去对指针类型的认识,先忘掉指针的类型,认识纯粹的指针,然后再重新认识带着类型的指针。
认识纯粹的指针
我们先抛开指针的类型
,看看指针是什么
1 |
|
output:
1 | int pointer = 8 bytes |
可以看到不管什么类型的指针的都是占用8个字节
(这个结果在64位机器上都是一致的),这种结果是容易理解的,我们知道,指针存储的是一个地址,所以不管什么类型的指针都必须要能够表示这台机器上所有的地址,所以对于32位的机器,指针需要4个字节,同理,如果是64位机器,指针就是8个字节。
64位机器中的64表示该机器有着64位的地址空间
为什么要讲上述这些内容呢,因为上述内容表达了一个重要信息,所谓指针,就是一个8个字节的数值,更具体一点的说,这个数值,其内涵是一个地址
。
对于指针的使用来说,既然其本质是一个值,也就意味着我们可以对它任意的赋值,至少在语法上我们不需要受到任何限制。
1 | int main(){ |
认识引用(&)
对于引用的本质其实相当的简单,我们起初接触&
时可能是在下面两种情景中
1 | int *a; |
上面我们提到了指针其实就是一个8字节的值,那么引用一个变量其实也是一个8字节的值
,也就是&b与1,2,3...这样的数值并无不同
。
那么我们可以进一步认识到,scanf中第二个参数接受的是一个变量的地址,这种用法并不与&
绑定,我们可以看下面的代码
1 |
|
input:
1 | 1 |
output:
1 | a = 1 |
通过上面的代码,不知道你是否可以认识到指针和引用其实就是一个值这一本质
。
指针的类型与解引用(*)
上面的内容都试图让你忘记指针的类型,理解指针就是一个值这个概念,那么指针的类型对于指针来说到底是什么呢,我们先来看一个简单的例子
1 |
|
看着下面的图,猜猜上面的输出是什么
output:
1 | *p = 0x12345678 |
看到这里,应该意识到了一点,指针的类型决定了指针在解引用获取多少字节的数据
,因为char类型占用一个字节,所以解引用时指针会向上看一个字节,同理,int类型占用四个字节,所以解引用时会向上看四个字节
那么现在我们可以先总结一下,指针可以分为两个部分看:
- 其本身是一个8字节的值,表示一个地址
- 指针的类型表示指针在解引用时获取多少字节的数据
指针的声明
如果理解了上面的内容,那么你对指针已经足够清楚了,但是实际上对于C初学者而言,指针最难的部分不在于理解它本身,而是在解读指针的声明,上这个部分与指针关系并不大,但是往往令人费解
比如我们早期遇到的指针数组和数组指针,不知道你现在看到是否可以分清楚,是有技巧还是靠记忆
1 | int *p[10]; |
关于这一块的内容,详见我的另一博客,我就不赘述了: C语言声明