zoukankan      html  css  js  c++  java
  • Delphi 中 "位" 的使用(1) 原始的二进制


    本话题涉及: 1、常用二进制的位操作; 2、集合与 "位" 的关系; 3、TBits 类.

    这里的 "位" 是指二进制位, 譬如一个 Byte 有 8 个位、一个 Integer 有 32 个位.
    在 C 语言中可以定义由 "位" 字段构成的结构体, 但因效率问题好像使用也不广泛.
    假如要保存八种状态(True/False), 最笨的办法可以使用下面的结构体:
    type
      TState = record
        b1, b2, b3, b4, b5, b6, b7, b8: Boolean;
      end;
    

    其实用 1 个字节就可以表示 8 种状态了, 因为 1 个字节就有 8 个位.
    这里是假定用每个位表示一个状态, 如果要算上各种组合这一个字节能表示 255 种情形.
    系统函数中的很多 "选项" 就是基于 "位".

    先来几个简单的关于 "位" 的练习:

    {这是查看二进制的函数}
    function ToBin(p: PByteArray; b: Integer): string;
    var
      i,j: Integer;
    begin
      Result := StringOfChar('0', b * 8);
      for i := 0 to b - 1 do for j := 0 to 7 do
        if Odd(p^[b-1-i] shr j) then Result[i*8 + 8 - j] := '1';
    end;
    
    {把一个二进制数赋给一个变量的方法}
    procedure TForm1.Button1Click(Sender: TObject);
    var
      b1,b2,b3: Byte;
    begin
      {虽 Delphi 常规下不支持二进制常量, 但其内嵌汇编支持}
      asm
        mov b1, 11100110B
      end;
      b2 := 230;
      b3 := $E6;
      {现在是给 b1 b2 b3 赋了同样的值}
      ShowMessageFmt('%d, %d, %d', [b1, b2, b3]); //230, 230, 230
    end;
    
    {使用 or 确保第二、三位是 1}
    procedure TForm1.Button2Click(Sender: TObject);
    var
      b1, b2: Byte;
    begin
      asm
        mov b1, 11100010B
        mov b2, 00000110B
      end;
      b1 := b1 or b2;
      ShowMessage(ToBin(@b1, 1)); {11100110}
    end;
    
    {使用 and 确保第二、三之外的位是 0}
    procedure TForm1.Button3Click(Sender: TObject);
    var
      b1, b2: Byte;
    begin
      asm
        mov b1, 11100010B
        mov b2, 00000110B
      end;
      b1 := b1 and b2;
      ShowMessage(ToBin(@b1, 1)); {00000010}
    end;
    
    {使用 and 探测第二、三位是否是 1}
    procedure TForm1.Button4Click(Sender: TObject);
    var
      b: Byte;
    begin
      asm mov b, 11100010B end;
      if 2 and b = 2 then ShowMessage('第二位是 1');
      {上面可以理解为: if 00000010B and b = 00000010B then ...}
      if 4 and b = 4 then ShowMessage('第三位是 1');
      {上面可以理解为: if 00000100B and b = 00000100B then ...}
    end;
    
    {使用 shr 探测第二、三位是否是 1}
    procedure TForm1.Button5Click(Sender: TObject);
    var
      b: Byte;
    begin
      asm mov b, 11100010B end;
      if Odd(b shr 1) then ShowMessage('第二位是 1');
      if Odd(b shr 2) then ShowMessage('第三位是 1');
    end;
    

    用一个 Byte 值保存八种状态的实例:

    准备工作:
    1、在空白窗体上添加 CheckListBox1;
    2、添加四个 Button, 并激活 Button1 的 OnClick 事件; 3、激活窗体的 OnCreate 事件.

    var b: Byte; {用它记录八个 CheckBox 的选择状态}
    
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      CheckListBox1.Items.CommaText := 'A,B,C,D,E,F,G,H';
      Button1.Caption := '保存状态';
      Button2.Caption := '恢复状态';
      Button3.Caption := '全选';
      Button4.Caption := '全不选';
      Button1.Tag := 1;
      Button2.Tag := 2;
      Button3.Tag := 3;
      Button4.Tag := 4;
      Button2.OnClick := Button1.OnClick;
      Button3.OnClick := Button1.OnClick;
      Button4.OnClick := Button1.OnClick;
    end;
    
    procedure TForm1.Button1Click(Sender: TObject);
    var
      i: Integer;
    begin
      if TButton(Sender).Tag = 1 then b := 0;
      for i := 0 to CheckListBox1.Count - 1 do
        case TButton(Sender).Tag of
          1: if CheckListBox1.Checked[i] then b := b or (1 shl i);
          2: CheckListBox1.Checked[i] := Odd(b shr i);
          3: CheckListBox1.Checked[i] := True;
          4: CheckListBox1.Checked[i] := False;
        end;
    end;
    

    测试效果图("恢复" 写成 "回复" 了):



    "位" 操作有点抽象, 用 "集合" 代替上面的操作就简明多了; 接下来讨论 "集合" 的本质.

  • 相关阅读:
    深入Android 【一】 —— 序及开篇
    Android中ContentProvider和ContentResolver使用入门
    深入Android 【六】 —— 界面构造
    The service cannot be activated because it does not support ASP.NET compatibility. ASP.NET compatibility is enabled for this application. Turn off ASP.NET compatibility mode in the web.config or add the AspNetCompatibilityRequirements attribute to the ser
    Dynamic Business代码片段总结
    对文件的BuildAction以content,resource两种方式的读取
    paraview 3.12.0 windows下编译成功 小记
    百度网盘PanDownload使用Aria2满速下载
    netdata的安装与使用
    用PS给证件照排版教程
  • 原文地址:https://www.cnblogs.com/del/p/1730115.html
Copyright © 2011-2022 走看看