sponsored links

C/C++基本数据类型

参考资料:

(1) 64位与32位编程的数据类型区别(C/C++): http://blog.csdn.net/harbinzju/article/details/5785024

(2) 指针运算: http://blog.csdn.net/hbuxiaoshe/article/details/5785575

C/C++仅仅定义了这些基本数据类型之间的关系,并没有定义严格定义它们的字长。在不同的平台上,根据编译器不同的实现,它们的字长如下表所示:


数据类型


LP64


ILP64


LLP64


ILP32


LP32


char


8


8


8


8


8


short


16


16


16


16


16


_int32


N/A


32


N/A


N/A


N/A


int


32


64


32


32


16


long


64


64


32


32


32


long long


N/A


N/A


64


N/A


N/A


pointer


64


64


64


32


32

在这张表中,LP64,ILP64,LLP64是64位平台上的字长模型,ILP32和LP32是32位平台上的字长模型。

LP64意思是long和pointer是64位,ILP64指 int,long,pointer是64位,LLP指long long和pointer是32-bit的。ILP32指int,long和pointer是32位的,LP32指long和pointer是32位的。

32位Windows采用的是ILP32数据模型,64位Windows采用的是LLP64数据模型。

所以,Windows上的32位程序设计和64位程序设计最大的不同(也就是IP32和LLP64的不同),就在于指针的长度不同??由32位变成了64位。

Win32 API在很多情况下,都需要将整数转换成指针或者相反。在 32 位的硬件上不会有问题,其中指针的大小和整数的大小是相同的,但在 64 位的硬件上却完全不一样。

为此M$搞了个所谓的“多态类型”:

对于特定的精度,您可以使用固定精度的数据类型。不管处理器的词大小如何,它们的大小都是一致的。大多数这些类型都在它们的名称中包含精度,可以从下面的表中看出:

表 1. 固定精度的数据类型
类型 定义

DWORD32


32 位无符号整数


DWORD64


64 位无符号整数


INT32


32 位有符号整数


INT64


64 位有符号整数


LONG32


32 位有符号整数


LONG64


64 位有符号整数


UINT32


无符号 INT32


UINT64


无符号 INT64


ULONG32


无符号 LONG32


ULONG64


无符号 LONG64

此外,当您需要数据类型的精度随着处理器词大小变化时,请使用指针精度数据类型。这些类型又称为“多态”数据类型。这些类型通常以 _PTR 后缀结尾,如下面的表格所示:

表 2. 指针精度的数据类型
类型 定义

DWORD_PTR


指针精度的无符号长类型


HALF_PTR


指针大小的一半。用于包含一个指针和两个小型字段的结构中


INT_PTR


指针精度的有符号整型


LONG_PTR


指针精度的有符号长类型


SIZE_T


指针可以引用的最大字节数。用于必须跨指针的整个范围的计数


SSIZE_T


有符号 SIZE_T


UHALF_PTR


无符号 HALF_PTR


UINT_PTR


无符号 INT_PTR


ULONG_PTR


无符号 LONG_PTR


LPARAM


与 LONG_PTR 为同义词,(在WTypes.h 中定义)


WPARAM


与 UINT_PTR 为同义词,(在 WTypes.h 中定义)

通过整数参数传递参数或上下文信息的所有 Win32 API 都更改为使用这些新的类型。

此外,还出现了定长指针:POINTER_32和POINTER_64:

#define POINTER_32 __ptr32

#define POINTER_64 __ptr64

PS:M$DN中说是在Basetsd.h中定义的

例1:虚函数和64位机上指针操作一个例题讲清

#include <iostream>
//#include <Basetsd.h>
#include <vector>
using namespace std;

/*
    深入理解虚函数实现机制:
    1. vptr(和对象实例的首地址相同) & vtable(属于类的数据)
    2.      p++,p--:指针p移动一个单位,这个单位大小是多少,要看p的数据类型了。如p是一个char型的,则p++移动一个字节,如果有int *p;则p++移动4个字节(默认32位机)。
    3.  32bit和64bit机上,int的长度都是32bit

        32bit机上,int*长度是32bit
        64bit机上,int*长度是64bit

    测试机器:Sam在百度实习时用的64位机器
*/

typedef void(*Fun)(void);

class Base{
public:
    virtual void f(){cout<<"f()"<<endl;}
private:
    virtual void g(){cout<<"g()"<<endl;}
};

int main(){
    //32bit和64bit机上,int的长度都是32bit
    cout<<sizeof(int)<<endl;    //4

    //32bit机上,int*长度是32bit
    //64bit机上,int*长度是64bit
    cout<<sizeof(int*)<<endl;   //8

    Base b;
    int* p1=(int*)*(int*)(&b);
    Fun f=(Fun)(int *)*p1;
    //64位机器上,一个函数指针的长度为64bit;32位置机器上一个函数指针的长度为32bit
    //Fun g=(Fun)(int *)*(p1+1); ==> 32bit机上这样用
    Fun g=(Fun)(int *)*(p1+2);
    f();    //f()
    g();    //g()

    return 0;
}
Tags: C/C++