sor*_*bro 15 c++ language-comparisons ada
C ++是否提供类似于Ada的subtype类型来缩小类型?
例如:
type Weekday is (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday);
subtype Working_Day is Weekday range Monday .. Friday;
Run Code Online (Sandbox Code Playgroud)
不,不是本地的。
您所描述的内容可能最好用一个范围枚举来表示,并带有一个单独的范围枚举和一个枚举子集,这些枚举与“父”范围枚举共享数字表示。
您可以进一步定义两者之间的某些转换,但是如果没有反思,就不可能使它们都优雅而直观,至少没有硬编码和重复的工作量(这很不利于此目的)是不可能的。
编程C ++时,最好完全放弃使用其他语言进行编程所产生的思维方式。
话虽如此,尽管我不会屏住呼吸,但这实际上是一个很好的功能构想!
解决方法:仅使用枚举,然后在需要的地方应用范围检查。
C++ 枚举和 Ada 枚举之间还有一些额外的区别。以下 Ada 代码演示了其中的一些差异。
with Ada.Text_IO; use Ada.Text_IO;
procedure Subtype_Example is
type Days is (Monday, Tueday, Wednesday, Thursday, Friday, Saturday, Sunday);
subtype Work_Days is Days range Monday..Friday;
begin
Put_Line("Days of the week:");
for D in Days'Range loop
Put_Line(D'Image);
end loop;
New_Line;
Put_Line("Days with classification:");
for D in Days'Range loop
Put(D'Image & " is a member of");
if D in Work_Days then
Put_Line(" Work_Days");
else
Put_Line(" a non-work day");
end if;
end loop;
end Subtype_Example;
Run Code Online (Sandbox Code Playgroud)
这个程序的输出是:
Days of the week:
MONDAY
TUEDAY
WEDNESDAY
THURSDAY
FRIDAY
SATURDAY
SUNDAY
Days with classification:
MONDAY is a member of Work_Days
TUEDAY is a member of Work_Days
WEDNESDAY is a member of Work_Days
THURSDAY is a member of Work_Days
FRIDAY is a member of Work_Days
SATURDAY is a member of a non-work day
SUNDAY is a member of a non-work day
Run Code Online (Sandbox Code Playgroud)
子类型 Work_Days 与类型 Days 具有 is-a 关系。Work_Days 的每个成员也是 Days 的成员。在此示例中,Work_Days 的有效值集是 Days 的有效值集的子集。
Ada 中的字符被定义为枚举。因此,为特殊用途定义 Character 类型的子类型很简单。以下示例从文件中读取文本并计算大写字母和小写字母的出现次数,忽略文件中的所有其他字符。
with Ada.Text_IO; use Ada.Text_IO;
procedure Count_Letters is
subtype Upper_Case is Character range 'A'..'Z';
subtype Lower_Case is Character range 'a'..'z';
Uppers : array(Upper_Case) of Natural;
Lowers : array(Lower_Case) of Natural;
File_Name : String(1..1024);
File_Id : File_Type;
Length : Natural;
Line : String(1..100);
begin
-- set the count arrays to zero
Uppers := (Others => 0);
Lowers := (Others => 0);
Put("Enter the name of the file to read: ");
Get_Line(Item => File_Name,
Last => Length);
-- Open the named file
Open(File => File_Id,
Mode => In_File,
Name => File_Name(1..Length));
-- Read the file one line at a time
while not End_Of_File(File_Id) loop
Get_Line(File => File_Id,
Item => Line,
Last => Length);
-- Count the letters in the line
for I in 1..Length loop
if Line(I) in Upper_Case then
Uppers(Line(I)) := Uppers(Line(I)) + 1;
elsif Line(I) in Lower_Case then
Lowers(Line(I)) := Lowers(Line(I)) + 1;
end if;
end loop;
end loop;
Close(File_Id);
-- Print the counts of upper case letters
for Letter in Uppers'Range loop
Put_Line(Letter'Image & " =>" & Natural'Image(Uppers(Letter)));
end loop;
-- print the counts of lower case letters
for Letter in Lowers'Range loop
Put_Line(Letter'Image & " =>" & Natural'Image(Lowers(Letter)));
end loop;
end Count_Letters;
Run Code Online (Sandbox Code Playgroud)
定义了两个 Character 子类型。子类型 Upper_Case 包含从“A”到“Z”的字符值范围,而子类型 Lower_Case 包含从“a”到“z”的字符值范围。
创建了两个数组来计算读取的字母。数组 Uppers 由 Upper_Case 值集索引。数组的每个元素都是 Natural 的一个实例,它是 Integer 的预定义子类型,仅包含非负值。数组Lowers 由Lower_Case 值集索引。Lowers 的每个元素也是 Natural 的一个实例。
程序会提示输入文件名,打开该文件,然后一次读取一行。解析每一行中的字符。如果字符是 Upper_Case 字符,则由解析的字母索引的 Uppers 中的数组元素递增。如果字符是Lower_Case 字符,则由解析的字母索引的Lowers 中的数组元素递增。
以下输出是读取 count_letters 程序的源文件的结果。
Enter the name of the file to read: count_letters.adb
'A' => 3
'B' => 0
'C' => 12
'D' => 0
'E' => 2
'F' => 13
'G' => 2
'H' => 0
'I' => 21
'J' => 0
'K' => 0
'L' => 36
'M' => 1
'N' => 9
'O' => 7
'P' => 4
'Q' => 0
'R' => 3
'S' => 2
'T' => 3
'U' => 9
'V' => 0
'W' => 0
'X' => 0
'Y' => 0
'Z' => 1
'a' => 51
'b' => 3
'c' => 8
'd' => 19
'e' => 146
'f' => 15
'g' => 16
'h' => 22
'i' => 50
'j' => 0
'k' => 0
'l' => 38
'm' => 13
'n' => 57
'o' => 48
'p' => 35
'q' => 0
'r' => 62
's' => 41
't' => 78
'u' => 19
'v' => 0
'w' => 12
'x' => 2
'y' => 6
'z' => 2
Run Code Online (Sandbox Code Playgroud)