作者:乱雪
来源:hi.baidu.com/lu4nx
R.E.C--F22叫我来篇稿,我实在不知道写啥,也很久没写过技术方面的东西了,刚看书时突然想到了写指针,所有的C语书上都把指针描述得很抽象,所以,老规矩,结合调试器+汇编来理解它。
其实指针和汇编中的间接寻址很像,抽象点说,运用指针可以间接性地访问某变量内容。我说得太抽象了,扔代码上来吧:
代码:
/* C语指针演示,by:乱雪 2010.1.21 */ #include <stdio.h> int main(void) { int count = 10,lx, *pointer; //定义两个整型变量count和lx,一个指针pointer。 pointer = &count; //把count的内存地址赋给pointer,“&”是C语中的地址运算符,用于取内存地址 lx = *pointer; //用“*”获得指针指向的内容,即 lx = 10 return 0; }
好了,进调试器来解释吧。编译环境VC6.0,调试器是VC6.0默认的调试器。需要观众有汇编语言的基础。
先在int count = 10,lx;处下个断点(右键“Insert/Remove Breakpoint”),然后按F5,进入调试状态后,会自动在断点处停下来,此时点在断点行处右键“Go To Disassembly”,来到汇编窗口。
这个时候断点处的代码如下:
代码:
mov dword ptr [ebp-4],0Ah

在这里顺便说下,我们定义了三个变量,分别是count、lx和pointer,那么分别对应的地址是ebp-4、ebp-8、ebp-0Ch,因为整型变量占4字节内存,每次ebp都会减少4。
根据刚才代码中的顺序,下一句是pointer = &count;,将pointer指向count的内存地址,我们看对应的汇编代码:
代码:
lea eax,[ebp-4] mov dword ptr [ebp-0Ch],eax
代码:
lea eax,[count] mov dword ptr [pointer],eax

看EAX的值正好是count变量的内存地址0012FF7C。然后在Watch窗口中输入pointer,可以看到pointer的内容是0x0012ff7c,如图:

说明pointer已经指到了count的内存地址了。
接下来看下一句代码lx = *pointer;,对应的汇编代码如下:
代码:
mov ecx,dword ptr [ebp-0Ch] mov edx,dword ptr [ecx] mov dword ptr [ebp-8],edx
代码:
mov ecx,dword ptr [pointer] mov edx,dword ptr [ecx] mov dword ptr [lx],edx

再单步运行一次,运行完指令mov edx,dword ptr [ecx],再看Registers窗口,EDX的值是0000000A,A是10的十六进制表示。

简单总结下就是:首先将变量的地址放入寄存器中,然后再取出寄存器中存放地址对应的值。C指针的内幕就这样,自己跟着调试一次代码,就会理解了。如有不足之处欢迎一起讨论:)