逻辑运算符把一个或多个logical表达式组合成新的真假结果。.not.用于取反,.and.、.or.用于组合条件,.eqv.与.neqv.用于判断两个逻辑值是否相同。它们常用于物理约束检查、设备状态组合和程序流程控制;当后一个条件只有在前一个条件成立后才安全时,应与分层if结构结合使用,而不能依赖短路求值。
语法结构
result = .not. a
result = a .and. b
result = a .or. b
result = a .eqv. b
result = a .neqv. b
- 运算对象和结果都是logical。在逻辑运算内部,.not.、.and.、.or.、.eqv./.neqv.的优先级依次降低;复杂条件宜加括号表达意图。
- .eqv.在两个逻辑值相同时为真,.neqv.在二者不同时为真;它们不是字符或数值的相等比较。
- Fortran不保证从左到右求值,也不保证.and.或.or.进行短路求值。数组下标、除法和有副作用的函数若需要前置保护,应放进嵌套if。
本文代码
! 组合设备状态,并用显式分支安全处理可能无效的计算。
program logicalOperatorsDemo
implicit none
real :: temperature, pressure, totalSignal, averageSignal
integer :: sampleCount
logical :: sensorOnline, temperatureOk, pressureOk
logical :: systemReady, alarmRequired, statesAgree, statesDiffer
temperature = 23.5
pressure = 101.2
sensorOnline = .true.
temperatureOk = temperature >= 18.0 .and. temperature <= 28.0
pressureOk = pressure >= 98.0 .and. pressure <= 105.0
systemReady = sensorOnline .and. temperatureOk .and. pressureOk
alarmRequired = .not. sensorOnline .or. .not. temperatureOk .or. .not. pressureOk
statesAgree = temperatureOk .eqv. pressureOk
statesDiffer = temperatureOk .neqv. pressureOk
print "(A,L1)", "温度合格:", temperatureOk
print "(A,L1)", "压力合格:", pressureOk
print "(A,L1)", "系统可运行:", systemReady
print "(A,L1)", "需要报警:", alarmRequired
print "(A,L1)", "两项状态相同:", statesAgree
print "(A,L1)", "两项状态不同:", statesDiffer
totalSignal = 0.0
sampleCount = 0
if (sampleCount > 0) then
averageSignal = totalSignal / real(sampleCount)
print "(A,F6.2)", "平均信号:", averageSignal
else
print "(A)", "样本数为0,跳过平均值计算"
end if
end program logicalOperatorsDemo
编译运行
(base) hong@hongdeMacBook-Pro 053.logicalOperators % gfortran -Wall -Wextra -std=f2018 exampleLogicalOperators.f90 -o logicalOperatorsDemo
(base) hong@hongdeMacBook-Pro 053.logicalOperators % ./logicalOperatorsDemo
温度合格:T
压力合格:T
系统可运行:T
需要报警:F
两项状态相同:T
两项状态不同:F
样本数为0,跳过平均值计算
现象分析
温度23.5位于18到28之间,压力101.2位于98到105之间,因此temperatureOk与pressureOk均为T;sensorOnline也是T,三者经.and.组合后systemReady为T。
alarmRequired对三个正常条件分别取反后再用.or.组合。三个否定结果均为F,所以不报警。两个合格状态同为T,因此.eqv.得到T、.neqv.得到F。
sampleCount为0。先用独立if判断样本数,再决定是否执行除法,因此不会计算totalSignal/0。这种结构不依赖编译器是否短路求值。
核心知识点
- .not.是一元取反;.and.、.or.、.eqv.和.neqv.是二元逻辑运算符。
- .eqv.比较真假状态是否相同,.neqv.比较真假状态是否不同。
- 复杂逻辑表达式应使用括号明确分组,避免仅凭优先级阅读。
- 不要把.and.或.or.当作安全保护机制;可能越界、除零或产生副作用的操作应放入显式分支。