文章目录
- if statements / expression
- if statements
- if expression
- Case Statement / Expression
- Case Statement
- Case Expression
- Loop Statement
- 基本循环结构 loop
- while loop
- For 循环
- Note
- For ... loop Control Variable
- For ... loop Range Evaluation
- Declare block (声明代码块)
- 反向遍历
- Exit Statement
- 无条件的 exit
- 有条件的 exit
- exit 到某一层循环
- Null Statements
- Condition Operators (条件运算符)
- Relation Operators(关系运算符)
- Logical Operators(逻辑运算符)
- Membership Operators (成员资格运算符)
- 练习
在 Ada 中,语句(Statements)是执行操作的主要工具,它们负责处理程序的控制流程和数据操作。以下是一些你需要特别注意的关键点:
分配语句(Assignment Statements):在 Ada 中,分配语句用于改变变量的值。分配语句的形式是:Variable := Expression;,注意 := 是分配操作符。
控制流语句(Control Flow Statements):Ada 提供了丰富的控制流语句,包括条件语句(如 if,case),循环语句(如 for,while,loop),以及异常处理语句(如 begin … exception)等。
过程调用(Procedure Calls):过程调用是一个语句,它执行一段预定义的代码。过程调用可能会改变程序的状态或执行某些动作。
返回语句(Return Statements):在函数中,返回语句用于结束函数的执行并返回一个值。
序列语句(Sequencing Statements):Ada 的语句通常按照它们在代码中出现的顺序执行。这个顺序可以通过使用复合语句(begin … end)来改变,复合语句允许你将多个语句组合成一个单独的语句。
异常语句(Exception Statements):Ada 提供了强大的异常处理机制,你可以使用 raise 语句来显式抛出异常,使用 begin … exception 结构来处理可能出现的异常。
中止语句(Abort Statements):Ada 支持并发编程,你可以使用中止语句来中止一个并发任务的执行。
在编写 Ada 语句时,需要注意语句的结束通常需要一个分号(;),这是 Ada 语法的一部分。此外,Ada 是强类型语言,所有的操作都必须在类型兼容的值之间进行,这在写表达式和分配语句时尤其重要。
if statements / expression
if statements
在 Ada 中,if
可以用作语句(Statement)或者表达式(Expression),这两者有一些不同的特性和用法。
- if 语句(If Statements):if 语句用于基于一个或多个条件执行不同的代码块。if 语句没有返回值,它的主要目标是改变程序的控制流。if 语句可以与
elsif,else
和end if
关键字一起使用来创建复杂的条件逻辑。例如:
if condition then
-- ... code to execute if condition is True
elsif other_condition then
-- ... code to execute if other_condition is True
else
-- ... code to execute if both conditions are False
end if;
if expression
- if 表达式(If Expressions):if 表达式是在 Ada 202x 标准中引入的新特性,也称为条件表达式(Conditional Expressions)。if 表达式用于根据一个条件计算两个不同的表达式之一的值。if 表达式总是有一个值,这个值可以被赋值给一个变量或用在其他表达式中。例如:
X := (if condition then expression1 else expression2);
Case Statement / Expression
Case Statement
case
语句:根据某个表达式的值来决定执行哪一段代码。语法如下:
case Expression is
when Value_1 => -- When Expression equals Value_1
-- Code to execute
when Value_2 =>
-- Code to execute
when others => -- When Expression doesn't match any of the above
-- Code to execute
end case;
case
语句必须覆盖所有可能的情况,这可以通过添加when others
来实现。- ada 中不需要使用
break
防止不同的case
之间的击穿行为
Case Expression
case
表达式:和 case 语句类似,但它返回一个值,而不是执行一段代码。语法如下:
Result := (case Expression is
when Value_1 => -- When Expression equals Value_1
-- Value to return
when Value_2 =>
-- Value to return
when others => -- When Expression doesn't match any of the above
-- Value to return
);
和 case 语句一样,case 表达式也必须覆盖所有可能的情况。
注意,case 语句和 case 表达式都只能用于离散类型(例如整数类型和枚举类型)。不允许用于实数类型或复杂的用户定义类型。
Loop Statement
基本循环结构 loop
loop
-- Statements
exit when Condition; -- Optional exit condition
end loop;
此结构将不断重复执行循环内的语句,直到遇到 exit 语句。exit
语句后面的 when
条件是可选的,如果省略,则 exit
将无条件地结束循环。
while loop
while Condition loop
-- Statements
end loop;
此结构将在条件为 True 时重复执行循环内的语句。一旦条件变为 False,循环将结束。
For 循环
for Index in Range loop
-- Statements
end loop;
此结构将为 Range
中的每个值执行循环内的语句。Index
是一个隐式声明的变量,其范围由 Range
定义。在循环内部,你可以使用 Index
,但不能修改它。
Note
For
循环的range
必须从小到大,例如这里的1 .. 10
- 如果从大到小的
range
则会导致一个“空”,进而导致loop
内的语句不执行:
- 如果非要实现逆向的遍历,请使用
reverse
关键字
For … loop Control Variable
- 理论上,一个完整的 for 循环应该写成:
-
也就是增加明确的类型限定,但如果没有指定,写成
for X in range 1..10 loop
那么 ada 会自动推断这个数据的类型 -
此外 ada 的
for
循环语句支持对 所有离散类型的变量 进行遍历
- 在这个例子中,程序会把
Character
中的所有可能的值遍历一遍。以下是代码的运行结果:A B C ... X Y Z
- 在这个例子中,程序会把
-
X
在运行过程中是不可改变的,是一个常量constant
For … loop Range Evaluation
- 在 Ada 中,for 循环的范围(range)是在循环开始之前进行一次求值的,并且在整个循环期间保持不变。这意味着循环范围的起始和终止值在循环开始时会被计算出来,并且在整个循环的执行过程中保持不变。
- 上图中,在
for
循环期间改变了B
的值,但这不会影响到for
循环的执行
- 上图中,在
Declare block (声明代码块)
在 Ada 中,你可以在 for
循环中使用 declare
块来引入局部变量。declare
块允许你在循环的上下文中声明和使用变量,这些变量的作用范围仅限于该 for 循环。
以下是一个示例代码,演示了在 for 循环中使用 declare 块引入局部变量的方法:
procedure For_Loop_Declare_Block is
begin
for i in 1..5 loop
declare
X : Integer := i * 10;
begin
Put_Line("i = " & Integer'Image(i) & ", X = " & Integer'Image(X));
end;
end loop;
end For_Loop_Declare_Block;
-
在上述代码中,
declare
块用于在for
循环中引入一个局部变量X
。X
的初始值是循环变量i
乘以10
。 -
输出结果:
i = 1, X = 10 i = 2, X = 20 i = 3, X = 30 i = 4, X = 40 i = 5, X = 50
-
在每次循环迭代时,
X
的值会根据i
的值重新计算,并在declare
块内部使用。注意,X
的作用范围仅限于declare
块内部,在块之外无法访问。 -
使用
declare
块可以帮助你在for
循环中引入临时变量,以便在循环体内部执行特定的计算或操作。这样可以提高代码的可读性和模块化。
反向遍历
你也可以使用 reverse
关键字来反向遍历范围:
for Index in reverse Range loop
-- Statements
end loop;
Exit Statement
- 在上面的
loop
中我们提到了exit
语句。在 Ada 语言中,exit 语句用于提前退出循环。它有两种形式:
无条件的 exit
- 直接使用
exit
关键字,这将立即结束当前循环。
loop
-- Some statements
exit; -- This will exit the loop unconditionally.
-- Some other statements
end loop;
有条件的 exit
exit
关键字后面可以跟when
子句,这样就只有当when
后面的条件为True
时,才会退出循环。
loop
-- Some statements
exit when Condition; -- This will exit the loop when the Condition is True.
-- Some other statements
end loop;
exit 到某一层循环
- 需要注意的是,如果你有嵌套的循环结构,并且希望从内层循环退出到某个特定的外层循环,你可以给外层循环一个名称,并在
exit
语句中指定这个名称。例如:
Outer: loop
-- Some statements
Inner: loop
-- Some other statements
exit Outer when Condition; -- This will exit the Outer loop when the Condition is True.
end loop Inner;
-- Even more statements
end loop Outer;
- 在这个例子中,当
Condition
为True
时,将直接退出到Outer
循环,而不仅仅是退出Inner
循环。这种指定循环名称的功能在处理复杂的嵌套循环时非常有用。
Null Statements
在 Ada 中,空语句(null statement)用于表示没有操作执行的语句。它是一个分号 ;
,用于在某些语法要求语句的位置上提供一个空语句。
空语句在以下情况下可以使用:
-
在需要语句但不需要执行任何操作的地方。例如,一个空的
if
分支或一个循环的空迭代。if Condition then null; -- 空的 if 分支 else -- Some statements end if;
for i in 1..10 loop -- 无操作的循环迭代 null; end loop;
-
在一行上需要一个语句但不需要执行任何操作的地方。例如,在一个代码块的最后一行。
begin -- Some statements null; -- 空语句 end;
Condition Operators (条件运算符)
在 Ada 中,有多种条件运算符(Condition Operators)可以用来创建条件表达式,这些表达式可用于 if 语句、while 语句或者其他需要布尔(Boolean)结果的地方。以下是一些常见的条件运算符:
Relation Operators(关系运算符)
关系运算符(Relational Operators):这些运算符用于比较两个值:
- =:等于
- /=:不等于
- <:小于
- <=:小于或等于
- >:大于
- >=:大于或等于
if X = Y then
-- ... code to execute if X is equal to Y
end if;
Logical Operators(逻辑运算符)
逻辑运算符(Logical Operators):这些运算符用于组合或反转布尔值:
- and:逻辑与
- or:逻辑或
- xor:逻辑异或
- not:逻辑非
if X > Y and Z < W then
-- ... code to execute if X is greater than Y and Z is less than W
end if;
- ada 中的
and
和or
运算符是不进行短路处理的(short-circuit),即,对于and
两边的内容哪怕左边已经False
了依然会检查右边表达式的值,同样的or
哪怕左边已经是True
了,依然也要检查右边的表达式- 但是对于
and then
和or else
则会进行 short-circuitand then
如果左边的表达式为False
,那么就不会计算右边的表达式,因为无论右边表达式的结果如何,整个and then
表达式的结果都已经确定为False
。or else
如果左边的表达式为True
,那么就不会计算右边的表达式,因为无论右边表达式的结果如何,整个or else
表达式的结果都已经确定为True
。
- 这种设计是为了让程序员可以明确地选择是否需要进行短路运算。
Membership Operators (成员资格运算符)
成员资格运算符(Membership Operators):这些运算符用于检查一个值是否在一个集合中:
- in:成员
- not in:非成员
例如:
if X in 1 .. 10 then
-- ... code to execute if X is between 1 and 10, inclusive
end if;
练习
- 应该用
=
来判断是否相等
- 用
case
应该覆盖到所有的情况,但是这里缺少了0
的情况1..9
覆盖了 1-9 的情况10..Integer'Last
包含了10到最大的Integer
的情况Integer'First .. -1
包含了Integer
中的最小值到-1
的情况- 唯独缺乏
A = 0
的处理操作
case
引导的情况同样不能发生重叠
case
只能针对离散的情况
I
在循环中是一个常量,其值不能被修改
range
的范围从10
到0
不会执行loop
中的内容
- 这是因为在进入循环的时候
X=1
虽然循环过程中X
改变成了10
但这不影响循环的次数。