指针在c中是个非常重要的概念,很多人在学习c语言的时候对指针的使用不太理解,我也一样,因此这篇文章主要总结我自己踩过的坑以及帮助初学c的同学从汇编视角理解指针。
知识点1:内存地址
内存是按字节编址的。32位即有2^32个寻址空间,每个地址空间含一个字节,最后也就是4GB大小。假设物理地址是8字节(地址总线3根)下,地址即为000,001,010,011,100,101,110,111(只是例子,实际内存地址是16进制)。总共8个组合,也就是8个地址。每个地址上的字节是用两个16进制表示的,整好8位1个字节大小。在这种情况下,一个指针变量的大小是3位,2的3次方正好就是那八个地址。因此在64位模式下,任何类型指针的大小都是64位8字节(此时的内存地址是虚拟内存地址,讨论c语言指针并不关注虚拟地址到实地址的转换)。
知识点2:大端小端
我们知道,在不同国家姓和名的顺序是不同的,比如在中国你叫张三,那在欧美国家人们往往称呼你为“三 张”。类似的案例出现在计算机中。小端序的意思即为低地址存放低位数据(以字节为单位,假设左边是低地址,4567小端方式是67 45而不是76 54)。
在计算机中有大端小端两种存放数据的方式,以小端序为例,假设我们要在0000这个地址上存放一个short类型变量,变量值为4660(16进制表示为1234),然后我们要把这个变量存储在0000这个位置,那么接下来会怎么做呢?答:往上“爬格子”,从0000开始爬,0000将会存储34,而一个short需要两个地址也就是16位,还需要再往上爬一个地址,所以0001存储12。在计算机中呈现出来就是 34 12,这个变量的起始地址就是0000。如果此时我们取short的地址,这个地址就是0000,将其赋给一个short型指针,这个指针就指向0000。在解引用读取的时候编译器会根据指针变量的类型自动帮你爬格子,比如short就爬两格,int爬四格(这也是导致了很多问题,比如指针强制转换后解引用造成的读越界,c语言中缺乏这样的保护机制)…
知识点3:副本
在函数main中调用另一个函数foo,b会在main中变成20吗?
int main()
{
int b = 10;
foo(b