本篇文章由 zg51747708 曾广 原创,未经允许不可以转载
今天,我们来聊聊int类型与指针这两者的特别关系
C语言和C++这两父子,有着一个共同的基因。那就是他们都有指针。指针的特点我就几句话概括下吧!有有点也有缺点。
优点:因为指针这个概念使得这两种语言非常接近去汇编语言。指针的操作能使得程序运行效率更高。
缺点:事物都有两面性,指针能使得程序效率更高是有代价的,那就是在复杂的情况下使得程序员十分难受,调试也是件麻烦事。因为根据地址,我们往往很难找到错误。
废话不多说,重点是int类型。先列举出基本的数据类型:int , float , char (float和double存储上没有太大区别我就不列举了)
这几种数据类型在VS2015自带编译器的字节大小分别占,int 4字节 ,float 4字节, char 1字节(当然指针在64位操作系统下是8字节,但是long long int在vs2015 Update3 也是8字节)
那我们要聊得另一个对象指针呢,指针在我的Window 7 64位上的32位程序中占4个字节。从字节数来看当然是与int和float类型更加亲近。那么int和float哪个关系更亲密呢。答案是int。
原因在于,两者中只有int类型的指针可以再转换为int类型,而float类型的指针不可以转换为float类型。那么这又能代表什么呢?下面的例子你会知道int类型的巨大作用。最后我会做总结。
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
例子,如果我想知道一个类的所以虚函数,在虚函数表中的位置顺序,来深入理解虚函数表的结构。我该怎么去做呢?这里就要使用到int类型和int型指针了。看下面我的代码。
//编译环境Windows 7 VS2015 Update3 //编译成32位程序
#include <iostream>
#include <stdlib.h>
using namespace std;
class A {
public:
virtual void a(void) {
cout << "A::a 函数发骚了" << endl;
}
virtual void b(void) {
cout << "A::b 函数发骚了" << endl;
}
virtual void c(void) {
cout << "A::c 函数发骚了" << endl;
}
};
int main() {
void (*fun)(void);//函数指针,其数据类型是void (*)(void)
A A_demo;
cout << &A_demo << endl;//输出的是A_demo对象的首地址
//(&A_demo)对象首地址
//*((int *)&A_demo)虚函数表首地址
//(*((int *)(*((int *)&A_demo))))虚函数表的第一个函数地址。
fun = (void(*)(void))(*((int *)(*((int *)&A_demo))));
fun();
fun = (void(*)(void))(*((int *)(*((int *)&A_demo)) + 1));
fun();
fun = (void(*)(void))(*((int *)(*((int *)&A_demo)) + 2));
fun();
system("pause");
return 0;
}
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
总结:从这里我就可以知道A_demo这个对象的虚函数表中的虚函数指针的排列顺序了。而且我也能知道虚函数表其实是一个函数指针数组。
这对于我们深入了解一些知识,有这巨大的帮助。因为在系统内部,唯一的标识就是内存地址。int类型与指针间的转换关系。能使得我们在没有外界的帮助下更好的了解内部的实现。从而学到更多。