一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

談談 Delphi 的類型與指針[2]

 工廠應用 2018-04-07
內存中的數(shù)據(jù)除了 0 便是 1, 你把它當作圖片、字符、數(shù)字等等, 那是你的事, 內存只認識 0 和 1.

Win32 系統(tǒng)除了使用硬內存以外, 還可以從硬盤上開辟虛擬內存;

因為 Win32 的內存地址范圍在 4 個 G 以內(0..232-1), 所以它最多能夠給一個應用程序分配 4G 的運行空間; 并且其中的 2G 有系統(tǒng)管理, 實際上程序只有 2G 的自主空間. 還記得有說 String 最大長度是 2G 嗎? 就是這個道理.

有 4G 的內存, 就有 4G 個地址, 也就是最多可以有 (1024*1024*1024*4 - 1 = 4294967295) 個內存地址, 這剛好是 Delphi 中 Cardinal 的最大值, 所以 32 位的指針類型追到底都是 Cardinal 類型的一個數(shù)字.

一個內存地址是 0..4294967295 之間的一個數(shù)字, 你可以通過內存地址讀取或寫入數(shù)據(jù);
一個指針要用來索引或標識內存, 它也是 0..4294967295 之間的一個數(shù)字; 它們雖不相同, 但通過指針可以找到實際存儲數(shù)據(jù)的內存地址, 并按指定的類型去讀寫它.

譬如:
var
  str: string;
  n: Cardinal;
  pstr: PString;
begin
  str := 'ABCDE';
  n := Cardinal(str); {獲取內存地址}
  pstr := @str;       {現(xiàn)在 pstr 是 str 的指針}

  {n 與 pstr 的數(shù)字結果是(結果是隨機的, 知道不一樣就行了):}
  ShowMessage(IntToStr(n));              {4571092}
  ShowMessage(IntToStr(Cardinal(pstr))); {1244652}

  {但通過 pstr 可以找到 str}
  ShowMessage(pstr^); {ABCDE}
end;

程序運行后, 字符串所在的內存基本上是下面這個樣子(以字節(jié)為單位), 上例中的 n 標識著 ↓ 的位置:
A B C D E

換二進制圖示一下:
00001010 00001011 00001100 00001101 00001110

如果只看二進制, 這個數(shù)據(jù)到底是什么很難知道; 再說它為什么非得是字符串 "ABCDE" 呢? 這可不一定.

下面的例子中, 我們先是權且把它當作字符串, 但隨著指針的移動, 字符串也在變化.

然后, 有分別把它分別用 Byte 指針(PByte) 和 Integer 指針(PInteger) 去讀取它, 也會得到相應的值.

完整示例如下:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  str: string;
  ps: PChar;
  n: Cardinal;
begin
  str := 'ABCDE';
  ps := PChar(str);
  n := Cardinal(ps);
  //n := Cardinal(str); {這行可以代替上面兩行}
  ShowMessage(IntToStr(n)); {結果是 Windows 隨機管理的}

  ShowMessage(PChar(n));   {ABCDE}
  ShowMessage(PChar(n+1)); {BCDE}
  ShowMessage(PChar(n+2)); {CDE}
  ShowMessage(PChar(n+3)); {DE}
  ShowMessage(PChar(n+4)); {E}
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  str: string;
  n: Cardinal;
  pb: PByte;
begin
  str := 'ABCDE';
  n := Cardinal(str);
  ShowMessage(IntToStr(n)); {4571140; 這是我這里的結果, 這是隨機的}

  pb := PByte(n);
  ShowMessage(IntToStr(pb^)); {65}
  pb := PByte(n+1);
  ShowMessage(IntToStr(pb^)); {66}
end;

procedure TForm1.Button3Click(Sender: TObject);
var
  str: string;
  n: Cardinal;
  pint: PInteger;
begin
  str := 'ABCDE';
  n := Cardinal(str);
  ShowMessage(IntToStr(n)); {4571140; 這是我這里的結果, 這是隨機的}

  pint := PInteger(n);
  ShowMessage(IntToStr(pint^)); {1145258561}
  pint := PInteger(n+1);
  ShowMessage(IntToStr(pint^)); {1162101570}
end;

end.

上面的第三個程序段的結果或許讓你迷惑:
第一個結果, 應該和 "ABCD" 有點關系才對啊, 怎么是: 1145258561 ?
第二個結果, 應該和 "BCDE" 有點關系才對啊, 怎么是: 1162101570 ?

為什么呢? 這當然沒錯, 聽我解釋:
1145258561 轉換成十六進制是: 44434241, 寫得清楚一點是: $44 $43 $42 $41; 還記得 Intel 等當下流行的 CPU 安排數(shù)據(jù)是倒著的嗎?

自己算算下一個, 用附件中的計算器即可.

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    国产精品午夜福利免费在线| 久久热九九这里只有精品| 久热99中文字幕视频在线| 中文字幕一区久久综合| 国产精品福利一级久久| 日韩欧美亚洲综合在线| 国产日韩在线一二三区| 亚洲国产婷婷六月丁香| 久久精品国产一区久久久| 午夜直播免费福利平台| 亚洲天堂国产精品久久精品| 久久这里只有精品中文字幕| 中文字幕日韩欧美亚洲午夜| 亚洲精品一二三区不卡| 白白操白白在线免费观看| 免费在线观看欧美喷水黄片| 成人综合网视频在线观看| 国产午夜福利不卡片在线观看| 男人操女人下面国产剧情| 五月激情综合在线视频| 欧美日韩国产精品黄片| 国产三级欧美三级日韩三级| 亚洲av日韩一区二区三区四区| 色哟哟国产精品免费视频| 亚洲精品熟女国产多毛| 偷拍偷窥女厕一区二区视频| 欧美精品一区久久精品| 好吊妞视频免费在线观看| 国产成人精品午夜福利av免费| 欧美黑人在线一区二区| 99久久精品免费精品国产| 欧美日韩免费观看视频| 日本在线视频播放91| 亚洲高清欧美中文字幕| 九七人妻一区二区三区| 亚洲做性视频在线播放| 欧美亚洲三级视频在线观看| 欧美日韩国内一区二区| 精品少妇一区二区视频| 日本高清不卡在线一区| 欧美一级内射一色桃子|