C++与Delphi数据类型的比较

 

 

Delphi

C++

MFC

无符号8

0~255

Byte

UCHAR

unsigned char

Byte

无符号16

0~65535

Word

USHORT

Unsigned short

Word

无符号32

0~ 4294967295

Cardinal

Longword

UINT

ULONG

DWORD

Unsigned int

Unsigned long

DWORD

UINT

 

 

 

 

有符号8

-128 .. 127

Shortint

SHORT

Ansichar

Char

Bool

 

有符号16

Smallint

Char(Widechar)

Short

wchar_t

 

有符号32

Longint

Single

Int

float

 

有符号64

double

double

 

 

 

 

 

 

#include 
#include 
#include "default.h"

using namespace std;

#pragma pack(push,1)                //在定义结构的时候一顶要用到pack(push,1)和下面的pack(pop) 
                                   //否则你构造的结构的长度会有问题 
typedef struct ethhdr              //以太网头部,长度14 
{ 
 unsigned char dst[6];      //目的的MAC地址 
 unsigned char src[6];      //源的MAC地址 
 unsigned short type;        //帧类型 
}ETHHDR,*PETHDHR; 

typedef struct eth_arphdr          //以太网arp字段长度28 
{ 
 unsigned short arp_hrd;    //硬件类型 
 unsigned short arp_pro;    //协议类型 
 unsigned char  arp_hln;    //硬件地址长度(6) 
 unsigned char  arp_pln;    //协议地址长度(4) 
 unsigned short arp_op;      //回应还是请求 

 unsigned char arp_sha[6];  //发送者MAC地址 
 unsigned long arp_spa;      //发送者IP 
 unsigned char arp_tha[6];  //接收者MAC地址 
 unsigned long arp_tpa;      //接收者IP 
}ETH_ARPHDR,*PETH_ARPHDR; 

typedef struct arp                  //整个ARP包的结构 
{ 
 ETHHDR ethhdr; 
 ETH_ARPHDR eth_arp; 
}ARP,*PARP; 
#pragma pack(pop)


int main(int argc, char *argv[])
{
    ETHHDR eth;
    ETH_ARPHDR arph;
    ARP arp1;   
    cout << "ETHHDR:" <


 

unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

const
  EPT_ARP = $0806; // 定义了一些在构造包的时候要用到的常量
  EPT_IP = $0800;
  ARP_HARDWARE = $0001;
  ARP_REPLY = $0002;
  ARP_REQUEST = $0001;

type
  PETHHDR = ^ETHHDR;

  ETHHDR = Packed record // 以太网头部,长度14
    dst: array [0 .. 5] of UCHAR; // 目的的MAC地址  unsign char- >byte
    src: array [0 .. 5] of UCHAR; // 源的MAC地址
    nType: USHORT; // 帧类型
  end;

type
  PETH_ARPHDR = ^eth_arphdr;

  eth_arphdr = Packed record // 以太网arp字段长度28
    arp_hrd: USHORT; // 硬件类型    unsign short- >word
    arp_pro: USHORT; // 协议类型
    arp_hln: UCHAR; // 硬件地址长度(6)
    arp_pln: UCHAR; // 协议地址长度(4)
    arp_op: USHORT; // 回应还是请求
    arp_sha: array [0 .. 5] of UCHAR; // 发送者MAC地址
    arp_spa: ULONG; // 发送者IP  unsigned long- >Longword
    arp_tha: array [0 .. 5] of UCHAR; // 接收者MAC地址  ************
    arp_tpa: ULONG; // 接收者IP
  end;

type
  PARP = ^arp;

  arp = Packed record // 整个ARP包的结构
    _ethhdr: ETHHDR;
    _eth_arphdr: eth_arphdr;
  end;

type
  MyRec = Packed Record
    var1: integer; // 4
    var2, var3, var4, var5, var6, var7, var8: shortint; // 1*7
    var9: integer; // 4
    var10: shortint; // 1
    var11: integer; // 4
    var12, var13: shortint; // 1*2
  end;

  {
    ShowMessage(intTostr(SizeOf(MyRec)));
    显示的结果应该为28,而不是22!用Packed的结果就是22。

    拟定义的数组比较大,应该用packed record!

    原因如下:

    在Windows中内存的分配一次是4个字节的。而Packed按字节进行内存的申请和分配,这样速度要慢一些,因为需要额外的时间来进行指针的定位。因此如果不用Packed的话,Delphi将按一次4个字节的方式申请内存,因此如果一个变量没有4个字节宽的话也要占4个字节!这样就浪费了。按上面的例子来说:

    var1:integer;//integer刚好4个字节!

    var2-var5占用4个字节,Var6-Var8占用4个字节,浪费了一个字节。

    var9:integer//占用4个字节;

    var10:占用4个字节;浪费3个字节

    var11:占用4个字节;

    var12,var13占用4个字节;浪费2个字节

    所以,如果不用packed的话,那么一共浪费6个字节!所以原来22个字节的记录需要28个字节的内存空间!

    这是因为在32位的环境中,所有变量分配的内存都进行“边界对齐”造成的。这样做可以对速度有优化作用;但是单个定义的变量至少会占用32位,即4个字节。所以会有长度误差,你可以用packed关键字取消这种优化。

    深入的分析,内存空间(不是内存地址)在计算机中划分为无数与总线宽度一致的单位,单位之间相接的地方称为“边界”;总线在对内存进行访问时,每次访问周期只能读写一个单位(32bit),如果一个变量横跨“边界”的话,则读或写这个变量就得用两个访问周期,而“边界对齐”时,只需一个访问周期,速度当然会有所优化。
  }
type
  TForm2 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
var
  com_arp: arp;
begin
  ShowMessage(IntToStr(SizeOf(com_arp._ethhdr))); // 14   14
  ShowMessage(IntToStr(SizeOf(com_arp._eth_arphdr))); // 32   28
  ShowMessage(IntToStr(SizeOf(com_arp))); // 48    42
  ShowMessage(IntToStr(SizeOf(MyRec))); // 28   22
end;

end.


调用WinAPI或C语言编写的DLL时,必须使用Packed Record。

你可能感兴趣的:(c/c++,delphi)