位域的Ada模式
在C语言中,使用某种形式的无符号字符或int来表示非排他条件是非常常见的,并且通过使用&|和~运算符,非常有效。根据我有限的Ada经验,Ada中的等效代码如以下代码所示位域的Ada模式,ada,Ada,在C语言中,使用某种形式的无符号字符或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 B
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;
这看起来有点笨重。有没有更好、更可爱的方式来使用这样的位图?您的位域到底想要实现什么?您似乎想使用Ada编写C。如果这是真的,那么考虑在艾达中使用模块化类型,在C.中使用无符号类型。 Ada 2012参考手册第4.5.1节规定: 对于模块化类型,预定义的逻辑运算符在 以位为基础,使用二进制表示 用于生成结果的二进制表示形式的操作数,其中为零 表示假,表示真。如果这个结果是外部的 类型的基本范围,最后由模数减去 执行以将结果带入类型的基本范围 阵列上的逻辑运算符是在 组件对组件的基础上匹配组件作为平等- 参见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#;
现在,您可以对颜色矩阵的实例执行所有熟悉的操作
编辑:
比较Ada表示子句和C/C++位字段的其他信息可以在中找到,您实际想用位字段实现什么?您似乎想使用Ada编写C。如果这是真的,那么考虑在艾达中使用模块化类型,在C.中使用无符号类型。 Ada 2012参考手册第4.5.1节规定: 对于模块化类型,预定义的逻辑运算符在 以位为基础,使用二进制表示 用于生成结果的二进制表示形式的操作数,其中为零 表示假,表示真。如果这个结果是外部的 类型的基本范围,最后由模数减去 执行以将结果带入类型的基本范围 阵列上的逻辑运算符是在 组件对组件的基础上匹配组件作为平等- 参见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#;
现在,您可以对颜色矩阵的实例执行所有熟悉的操作
编辑:
比较Ada表示子句和C/C++位字段的其他信息可以在中找到。它确实取决于您尝试执行的操作 通常,您会看到反复使用&| ~>运算符,有时甚至是&&| |,并且很容易在C中获得错误的掩码值来设置、清除或测试单个位,例如在位字段类型中打开或关闭红色,而不是直接访问位:
MyBitField(Red) := TRUE;
If MyBitField(Orange) then ...
有趣的是,对于具有位集、清除和测试指令的微控制器,编译器将C代码翻译成明显的简单指令是一项相当困难的工作。这取决于您尝试执行的操作 通常,您会看到反复使用&| ~>运算符,有时甚至是&&| |,并且很容易在C中获得错误的掩码值来设置、清除或测试单个位,例如在位字段类型中打开或关闭红色,而不是直接访问位:
MyBitField(Red) := TRUE;
If MyBitField(Orange) then ...
有趣的是,对于具有位集、清除和测试指令的微控制器来说,编译器将C代码翻译成明显的简单指令是一项相当困难的工作。我真的不应该把周六的时间花在学生的家庭作业上- 尽量移动到声明部分。您可以这样做:
-- Warning: Not tested
with Ada.Text_IO;
procedure Bit_Fields is
type Typ_Counter is range 0 .. 1_000_000; -- Fix this!
package Counter_Io is new Ada.Text_Io.Integer_Io (Typ_Counter);
procedure Increment (Counter : in out Typ_Counter; On_Condition : Boolean) is
begin
if On_Condition then
Counter := Counter + 1; -- May overflow!
end if;
end Increment;
type Typ_Colour is mod 2**8 with Size => 8; -- Look into this!
Colour_Max : constant Typ_Colour := Typ_Colour'Last;
Colour_None : constant Typ_Colour := Typ_Colour'First;
type Knd_Colour is (Red, Green, Blue, Orange, Yellow, Purple);
type Arr_Colour is array (Knd_Colour) of Typ_Colour;
None : constant Arr_Colour := (others => Colour_None);
Max : constant Arr_Colour := (others => Colour_Max);
generic
with function Operation (Left, Right : Typ_Colour) return Typ_Colour;
function Generic_Operation (Left, Right : Arr_Colour) return Arr_Colour;
function Generic_Operation (Left, Right : Arr_Colour) return Arr_Colour
is
Result : Arr_Colour;
begin
for Gun in Result'Range loop
Result (Gun) := Operation (Left => Left (Gun),
Right => Right (Gun));
end loop;
return Result;
end Generic_Operation;
function "or" is new Generic_Operation (Operation => "or");
function "and" is new Generic_Operation (Operation => "and");
My_Colours : Arr_Colour;
My_Other_Colours : Arr_Colour;
Counter : Typ_Counter := 0;
begin
My_Colours := (Red => not Colour_Max, others => Colour_None);
My_Other_Colours := (Red => Colour_Max, others => Colour_None);
Increment (Counter, On => (My_Other_Colours or My_Colours) = Max);
Increment (Counter, On => (My_Colours and My_Other_Colours) = None);
declare
use Ada.Text_Io, Counter_IO;
begin
Put ("Counter is ");
Put (Counter, Width => 0);
New_Line;
end;
end Bit_Fields;
我真的不应该把周六的时间花在给学生做作业上- 尽量移动到声明部分。您可以这样做:
-- Warning: Not tested
with Ada.Text_IO;
procedure Bit_Fields is
type Typ_Counter is range 0 .. 1_000_000; -- Fix this!
package Counter_Io is new Ada.Text_Io.Integer_Io (Typ_Counter);
procedure Increment (Counter : in out Typ_Counter; On_Condition : Boolean) is
begin
if On_Condition then
Counter := Counter + 1; -- May overflow!
end if;
end Increment;
type Typ_Colour is mod 2**8 with Size => 8; -- Look into this!
Colour_Max : constant Typ_Colour := Typ_Colour'Last;
Colour_None : constant Typ_Colour := Typ_Colour'First;
type Knd_Colour is (Red, Green, Blue, Orange, Yellow, Purple);
type Arr_Colour is array (Knd_Colour) of Typ_Colour;
None : constant Arr_Colour := (others => Colour_None);
Max : constant Arr_Colour := (others => Colour_Max);
generic
with function Operation (Left, Right : Typ_Colour) return Typ_Colour;
function Generic_Operation (Left, Right : Arr_Colour) return Arr_Colour;
function Generic_Operation (Left, Right : Arr_Colour) return Arr_Colour
is
Result : Arr_Colour;
begin
for Gun in Result'Range loop
Result (Gun) := Operation (Left => Left (Gun),
Right => Right (Gun));
end loop;
return Result;
end Generic_Operation;
function "or" is new Generic_Operation (Operation => "or");
function "and" is new Generic_Operation (Operation => "and");
My_Colours : Arr_Colour;
My_Other_Colours : Arr_Colour;
Counter : Typ_Counter := 0;
begin
My_Colours := (Red => not Colour_Max, others => Colour_None);
My_Other_Colours := (Red => Colour_Max, others => Colour_None);
Increment (Counter, On => (My_Other_Colours or My_Colours) = Max);
Increment (Counter, On => (My_Colours and My_Other_Colours) = None);
declare
use Ada.Text_Io, Counter_IO;
begin
Put ("Counter is ");
Put (Counter, Width => 0);
New_Line;
end;
end Bit_Fields;
pragma包是一个提示,编译器可以随意忽略它。您要为BitFieldType'Component\u大小使用1;相反,一点也不笨重!它非常实用,特别是对于大型枚举类型。GNAT和其他编译器可能会为此生成非常高效的机器代码。我只编写COLOR_集而不是BITFELDTYPE和Purple_集等,而不是PIPPLEBITFELD。您更多地考虑数学对象,而较少考虑它是如何实现的……pragma包是一个提示,编译器可以随意忽略它。您要为BitFieldType'Component\u大小使用1;相反,一点也不笨重!它非常实用,特别是对于大型枚举类型。GNAT和其他编译器可能会为此生成非常高效的机器代码。我只编写COLOR_集而不是BITFELDTYPE和Purple_集等,而不是PUPPLEBITFIEL
D您更多地考虑数学对象,而较少考虑它是如何实现的……很容易使这些二进制值出错!不像在C语言中用hexTrue编写代码那么简单,但这就是为什么我使用二进制表示法,并将代码格式化为一个表,这样人们就可以更容易地直观地检查值。很容易让那些二进制值出错!不像在C中用hexTrue编写代码那样简单,但这就是为什么我使用二进制表示法,并将代码格式化为一个表,以便更容易直观地检查值。