首页 > 解决方案 > 位域的 Ada 模式

问题描述

在 C 中,使用某种 unsigned char 或 int 形式的位来表示非排他条件是非常常见的,并且通过使用 & | 和 ~ 运算符,效率极高。根据我有限的 Ada 经验,Ada 中的等价物将如以下代码所示。

with Ada.Text_IO;   use Ada.Text_IO;

procedure Main is

   type Colours is (Red, Green, Blue, Orange, Yellow, Purple);

   type BitFieldType is array (Colours) of Boolean;
   pragma Pack (BitFieldType);

   RedBitField : constant BitFieldType := (Red => True, others => False);
   GreenBitField : constant BitFieldType := (Green => True, others => False);
   BlueBitField : constant BitFieldType := (Blue => True, others => False);
   OrangeBitField : constant BitFieldType := (Orange => True, others => False);
   YellowBitField : constant BitFieldType := (Yellow => True, others => False);
   PurpleBitField : constant BitFieldType := (Purple => True, others => False);
   NoColourBitField   : constant BitFieldType := (others => False);
   AllColoursBitField : constant BitFieldType := (others => True);

   MyBitField      : BitFieldType;
   MyOtherBitField : BitFieldType;
   Counter         : Integer := 0;

begin
   MyBitField      := not RedBitField;
   MyOtherBitField := RedBitField;

   if (MyOtherBitField or MyBitField) = AllColoursBitField then
      Counter := Counter + 1;
   end if;

   if (MyBitField and MyOtherBitField) = NoColourBitField then
      Counter := Counter + 1;
   end if;

   Put_Line ("Counter is " & Integer'image (Counter));

end Main;

这显得有些笨拙。有没有更好、更 Lovelacey 的方式来使用这样的位图?

标签: ada

解决方案


你实际上想用你的位域实现什么?您似乎想使用 Ada 编写 C。如果这是真的,那么考虑在 Ada 中使用模块化类型,而在 C 中使用无符号类型。

Ada 2012 参考手册第 4.5.1 节指出:

对于模块化类型,预定义的逻辑运算符是逐位定义的,使用操作数的值的二进制表示来产生结果的二进制表示,其中 0 表示 False,1 表示 True。如果此结果超出类型的基本范围,则执行最后的模数减法以将结果带入类型的基本范围。

数组上的逻辑运算符是在匹配组件的基础上逐个组件执行的(关于相等性 - 参见 4.5.2),使用组件类型的预定义逻辑运算符。结果数组的边界是左操作数的边界。

例如,您的示例的无符号类型可以定义为

type Color_Matrix is mod 2**6;
Red        : constant Color_Matrix := 2#100000#;
Green      : constant Color_Matrix := 2#010000#;
Blue       : constant Color_Matrix := 2#001000#;
Orange     : constant Color_Matrix := 2#000100#;
Yellow     : constant Color_Matrix := 2#000010#;
Purple     : constant Color_Matrix := 2#000001#;
No_Color   : constant Color_Matrix := 0;
All_Colors : constant Color_Matrix := 2#111111#;

您现在可以对 Color_Matrix 的实例执行所有熟悉的操作。

编辑: 可以在https://sworthodoxy.blogspot.com/2014/03/ada-vs-c-bit-fields.html找到比较 Ada 表示子句和 C/C++ 位域的其他信息


推荐阅读