我们既可以把节点NODE的地址看是NODE*,也可以堪称是NODE**,两者之间有差别吗?(其实没有区别)
linux 内核代码上面有一种计算偏移值的方法,大家可以参考一下:
int offset = (int)&(((NODE*)(0))->next); |
(6)class指针
class指针比较复杂,不过大家可以从一个小范例看出一些端倪:
class fruit class apple : public fruit void process() |
熟悉C++的朋友可以很快知道这道题目的答案了,那么为什么a和b都指向同一个地址,使用了相同的print函数,但是结果不同。我想这主要是因为两者数据类型不同的缘故。一旦指针和某一种数据类型绑在了一起,那么这个指针的所有行为事实上都已经被这种类型的数据所限定了。普通数据类型是这样,自定义的class类型也是这样。只要不是在print函数前面加上virtual,我们就会发现两个print的调用都是硬编码,和普通的函数调用无异。所以说,指针离不开数据类型,离开具体类型的地址是没有意义的。就像void*是可以原谅的,但是void却是万万不能接受的。下面的汇编代码很好的说明了这一点。
65: fruit f; 0040132D lea ecx,[ebp-10h] 00401330 call @ILT+35(fruit::fruit) (00401028) 00401335 mov dword ptr [ebp-4],0 66: apple* a = (apple*)&f; 0040133C lea eax,[ebp-10h] 0040133F mov dword ptr [ebp-14h],eax 67: a->print(); 00401342 mov ecx,dword ptr [ebp-14h] 00401345 call @ILT+0(apple::print) (00401005) 68: fruit* b = &f; 0040134A lea ecx,[ebp-10h] 0040134D mov dword ptr [ebp-18h],ecx 69: b->print(); 00401350 mov ecx,dword ptr [ebp-18h] 00401353 call @ILT+25(fruit::print) (0040101e) |
(全文完)
【预告: 下面一篇博客主要讨论汇编语言和流程控制】
相关链接: