Day 4: 运算符与表达式
🎯 学习目标
- 理解 PowerShell 中各种运算符的作用和用法
- 掌握算术运算符进行数学计算
- 学会比较运算符进行条件判断
- 使用逻辑运算符组合多个条件
- 了解字符串运算符的特殊用法
- 掌握运算符的优先级规则
💡 核心概念
什么是运算符?
运算符是用于执行操作的符号或关键字。在 PowerShell 中,运算符可以用于:
- 数学计算
- 字符串操作
- 比较值的大小
- 逻辑判断
- 类型转换
什么是表达式?
表达式是由运算符、操作数(变量、值、函数调用等)组合而成的式子,可以被 PowerShell 求值并产生结果。
示例:
# 简单表达式
5 + 3
# 复杂表达式
($age -ge 18) -and ($hasLicense -eq $true)
📝 算术运算符
算术运算符用于执行数学运算。
基本算术运算符
| 运算符 | 名称 | 示例 | 结果 |
|---|---|---|---|
+ |
加法 | 5 + 3 |
8 |
- |
减法 | 10 - 4 |
6 |
* |
乘法 | 6 * 7 |
42 |
/ |
除法 | 15 / 3 |
5 |
% |
取模(余数) | 10 % 3 |
1 |
示例代码
# 基本算术运算
$a = 10
$b = 3
$sum = $a + $b # 13
$difference = $a - $b # 7
$product = $a * $b # 30
$quotient = $a / $b # 3.3333...
$remainder = $a % $b # 1
Write-Host "加法: $sum"
Write-Host "减法: $difference"
Write-Host "乘法: $product"
Write-Host "除法: $quotient"
Write-Host "余数: $remainder"
实际应用:计算购物总价
# 场景:计算购物总价
$price = 59.9
$quantity = 3
$taxRate = 0.08
# 计算小计
$subtotal = $price * $quantity
# 计算税额
$tax = $subtotal * $taxRate
# 计算总价
$total = $subtotal + $tax
Write-Host "商品单价: ¥$price"
Write-Host "购买数量: $quantity"
Write-Host "小计: ¥$subtotal"
Write-Host "税额: ¥$tax"
Write-Host "总价: ¥$total"
📝 赋值运算符
赋值运算符用于给变量赋值。
常用赋值运算符
| 运算符 | 名称 | 示例 | 等价于 |
|---|---|---|---|
= |
简单赋值 | $a = 5 |
– |
+= |
加并赋值 | $a += 3 |
$a = $a + 3 |
-= |
减并赋值 | $a -= 2 |
$a = $a - 2 |
*= |
乘并赋值 | $a *= 4 |
$a = $a * 4 |
/= |
除并赋值 | $a /= 2 |
$a = $a / 2 |
%= |
取模并赋值 | $a %= 3 |
$a = $a % 3 |
示例代码
# 基本赋值
$count = 0
Write-Host "初始值: $count" # 0
# 加并赋值
$count += 5
Write-Host "加5后: $count" # 5
# 减并赋值
$count -= 2
Write-Host "减2后: $count" # 3
# 乘并赋值
$count *= 4
Write-Host "乘4后: $count" # 12
# 除并赋值
$count /= 3
Write-Host "除以3后: $count" # 4
实际应用:计数器
# 场景:统计文件数量
$fileCount = 0
# 模拟处理多个文件
$files = @("doc1.txt", "doc2.txt", "doc3.txt", "doc4.txt")
foreach ($file in $files) {
Write-Host "处理文件: $file"
$fileCount += 1 # 每处理一个文件,计数器加1
}
Write-Host "`n总共处理了 $fileCount 个文件"
📝 比较运算符
比较运算符用于比较两个值,返回 True 或 False。
PowerShell 特殊语法
⚠️ 重要:PowerShell 的比较运算符不是传统的符号(如 ==, >, <),而是字母组合!
| 运算符 | 名称 | 示例 | 说明 |
|---|---|---|---|
-eq |
等于 | 5 -eq 5 |
等于返回 True |
-ne |
不等于 | 5 -ne 3 |
不等于返回 True |
-gt |
大于 | 10 -gt 5 |
大于返回 True |
-ge |
大于等于 | 10 -ge 10 |
大于等于返回 True |
-lt |
小于 | 3 -lt 5 |
小于返回 True |
-le |
小于等于 | 3 -le 3 |
小于等于返回 True |
大小写不敏感版本
| 运算符 | 说明 |
|---|---|
-ieq, -ine, -igt, -ige, -ilt, -ile` |
显式大小写不敏感(默认) |
-ceq, -cne, -cgt, -cge, -clt, -cle |
大小写敏感 |
示例代码
# 数值比较
$age = 25
$isAdult = $age -ge 18
Write-Host "是否成年: $isAdult" # True
$isSenior = $age -ge 60
Write-Host "是否老年: $isSenior" # False
# 字符串比较(默认大小写不敏感)
$name1 = "PowerShell"
$name2 = "powershell"
$isSame = $name1 -eq $name2
Write-Host "名称相同: $isSame" # True(因为不区分大小写)
# 字符串比较(大小写敏感)
$isSameCase = $name1 -ceq $name2
Write-Host "名称完全相同: $isSameCase" # False(区分大小写)
实际应用:成绩判断
# 场景:判断成绩等级
$score = 85
if ($score -ge 90) {
Write-Host "优秀"
} elseif ($score -ge 80) {
Write-Host "良好"
} elseif ($score -ge 60) {
Write-Host "及格"
} else {
Write-Host "不及格"
}
# 输出: 良好
📝 逻辑运算符
逻辑运算符用于组合多个条件,返回 True 或 False。
基本逻辑运算符
| 运算符 | 名称 | 说明 | 示例 |
|---|---|---|---|
-and |
与 | 两个条件都为 True 时返回 True | $age -ge 18 -and $hasLicense |
-or |
或 | 两个条件任一为 True 时返回 True | $isStudent -or $isSenior |
-xor |
异或 | 两个条件有且仅有一个为 True 时返回 True | $a -xor $b |
-not |
非 | 取反 | -not ($isReady) |
! |
非 | -not 的简写 |
! $isReady |
逻辑运算符真值表
| A | B | A -and B | A -or B | A -xor B |
|---|---|---|---|---|
| True | True | True | True | False |
| True | False | False | True | True |
| False | True | False | True | True |
| False | False | False | False | False |
示例代码
# -and 运算符:两个条件都必须为真
$age = 25
$hasLicense = $true
$canDrive = ($age -ge 18) -and $hasLicense
Write-Host "可以开车: $canDrive" # True
# -or 运算符:至少一个条件为真
$isStudent = $false
$isSenior = $true
$hasDiscount = $isStudent -or $isSenior
Write-Host "有折扣: $hasDiscount" # True
# -not 运算符:取反
$isReady = $false
$isNotReady = -not $isReady
Write-Host "未准备好: $isNotReady" # True
实际应用:登录验证
# 场景:用户登录验证
$username = "admin"
$password = "secret123"
$isActive = $true
$isLocked = $false
# 验证条件:用户名正确 且 密码正确 且 账户激活 且 未锁定
$isValid = ($username -eq "admin") -and `
($password -eq "secret123") -and `
$isActive -and `
(-not $isLocked)
if ($isValid) {
Write-Host "登录成功!"
} else {
Write-Host "登录失败,请检查用户名和密码。"
}
实际应用:文件筛选
# 场景:查找大文件且最近修改过的文件
$files = Get-ChildItem "C:\Logs"
foreach ($file in $files) {
# 筛选条件:大于1MB 且 在7天内修改过
if (($file.Length -gt 1MB) -and ($file.LastWriteTime -gt (Get-Date).AddDays(-7))) {
Write-Host "发现大文件: $($file.Name) - 大小: $([math]::Round($file.Length / 1MB, 2)) MB"
}
}
📝 字符串运算符
字符串运算符用于字符串的比较和操作。
字符串比较运算符
| 运算符 | 名称 | 说明 |
|---|---|---|
-eq, -ne, -gt, -ge, -lt, -le |
比较 | 按字母顺序比较 |
-like, -notlike |
通配符匹配 | 支持通配符 *, ?, [] |
-match, -notmatch |
正则表达式匹配 | 使用正则表达式 |
字符串连接运算符
| 运算符 | 名称 | 示例 | 结果 |
|---|---|---|---|
+ |
连接 | "Hello" + " " + "World" |
"Hello World" |
* |
重复 | "A" * 5 |
"AAAAA" |
示例代码
# 字符串连接
$firstName = "张"
$lastName = "三"
$fullName = $firstName + $lastName
Write-Host "姓名: $fullName" # 张三
# 字符串重复
$separator = "-" * 20
Write-Host $separator # --------------------
# 通配符匹配
$filename = "report2024.xlsx"
$isExcelFile = $filename -like "*.xlsx"
Write-Host "是Excel文件: $isExcelFile" # True
# 正则表达式匹配
$email = "user@example.com"
$isValidEmail = $email -match "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"
Write-Host "有效邮箱: $isValidEmail" # True
实际应用:文件筛选
# 场景:筛选特定类型的文件
$files = @("report.docx", "data.xlsx", "image.jpg", "backup.zip", "summary.docx")
foreach ($file in $files) {
# 筛选 Word 文档
if ($file -like "*.docx") {
Write-Host "Word文档: $file"
}
}
# 输出:
# Word文档: report.docx
# Word文档: summary.docx
实际应用:数据验证
# 场景:验证输入数据格式
$phone = "13812345678"
# 验证手机号格式(11位数字)
$isValidPhone = $phone -match "^\d{11}$"
if ($isValidPhone) {
Write-Host "手机号格式正确"
} else {
Write-Host "手机号格式错误"
}
📝 运算符优先级
当一个表达式中包含多个运算符时,PowerShell 按照优先级顺序执行。
优先级从高到低
| 优先级 | 运算符类型 | 运算符 |
|---|---|---|
| 1(最高) | 括号 | () |
| 2 | 一元运算符 | -, +, --, ++, !, -not |
| 3 | 乘除模 | *, /, % |
| 4 | 加减 | +, - |
| 5 | 比较运算符 | -eq, -ne, -gt, -ge, -lt, -le |
| 6 | 逻辑与 | -and |
| 7(最低) | 逻辑或 | -or |
示例代码
# 优先级示例
$result1 = 2 + 3 * 4 # 结果: 14(先乘后加)
$result2 = (2 + 3) * 4 # 结果: 20(括号优先)
Write-Host "2 + 3 * 4 = $result1" # 14
Write-Host "(2 + 3) * 4 = $result2" # 20
# 逻辑运算符优先级
$age = 25
$isStudent = $true
# -and 优先级高于 -or
$result3 = $age -lt 18 -or $isStudent -and $age -lt 25
# 相当于: $age -lt 18 -or ($isStudent -and $age -lt 25)
# False -or (True -and False) = False
Write-Host "结果: $result3" # False
# 使用括号明确优先级
$result4 = ($age -lt 18 -or $isStudent) -and $age -lt 25
# (False -or True) -and False = False
Write-Host "结果: $result4" # False
建议
⚠️ 重要:当表达式复杂时,始终使用括号明确优先级,即使默认顺序正确也要加括号。这样做的好处是:
- 代码更易读
- 避免歧义
- 防止未来维护时出错
# 推荐:使用括号
$isValid = ($age -ge 18) -and ($hasLicense -eq $true)
# 不推荐:依赖默认优先级
$isValid = $age -ge 18 -and $hasLicense -eq $true
🎮 完整实战示例
示例1:计算器脚本
# 场景:简单计算器
Write-Host "=== PowerShell 计算器 ===" -ForegroundColor Cyan
Write-Host ""
# 获取用户输入
$num1 = Read-Host "请输入第一个数字"
$operator = Read-Host "请输入运算符 (+, -, *, /, %)"
$num2 = Read-Host "请输入第二个数字"
# 转换为数字
$number1 = [double]$num1
$number2 = [double]$num2
# 计算结果
$result = 0
$isValid = $true
switch ($operator) {
"+" { $result = $number1 + $number2 }
"-" { $result = $number1 - $number2 }
"*" { $result = $number1 * $number2 }
"/" {
if ($number2 -eq 0) {
Write-Host "错误:除数不能为零!" -ForegroundColor Red
$isValid = $false
} else {
$result = $number1 / $number2
}
}
"%" { $result = $number1 % $number2 }
default {
Write-Host "错误:不支持的运算符!" -ForegroundColor Red
$isValid = $false
}
}
# 显示结果
if ($isValid) {
Write-Host ""
Write-Host "计算结果: $number1 $operator $number2 = $result" -ForegroundColor Green
}
示例2:温度转换器
# 场景:温度单位转换(摄氏度 ↔ 华氏度)
Write-Host "=== 温度转换器 ===" -ForegroundColor Cyan
Write-Host ""
# 获取用户输入
$temp = Read-Host "请输入温度值"
$unit = Read-Host "请选择单位 (C=摄氏度, F=华氏度)"
# 转换为数字
$temperature = [double]$temp
# 转换温度
if ($unit -eq "C" -or $unit -eq "c") {
# 摄氏度转华氏度
$fahrenheit = $temperature * 9 / 5 + 32
Write-Host "$temperature°C = $fahrenheit°F"
} elseif ($unit -eq "F" -or $unit -eq "f") {
# 华氏度转摄氏度
$celsius = ($temperature - 32) * 5 / 9
Write-Host "$temperature°F = $celsius°C"
} else {
Write-Host "无效的单位!" -ForegroundColor Red
}
示例3:成绩统计系统
# 场景:学生成绩统计
Write-Host "=== 成绩统计系统 ===" -ForegroundColor Cyan
Write-Host ""
# 获取学生成绩
$chinese = [int](Read-Host "语文成绩")
$math = [int](Read-Host "数学成绩")
$english = [int](Read-Host "英语成绩")
# 计算总分和平均分
$totalScore = $chinese + $math + $english
$averageScore = $totalScore / 3
# 四舍五入到两位小数
$averageScore = [math]::Round($averageScore, 2)
Write-Host ""
Write-Host "=== 成绩单 ===" -ForegroundColor Green
Write-Host "语文: $chinese"
Write-Host "数学: $math"
Write-Host "英语: $english"
Write-Host "总分: $totalScore"
Write-Host "平均分: $averageScore"
Write-Host ""
# 判断等级
if ($averageScore -ge 90) {
Write-Host "等级: 优秀" -ForegroundColor Green
} elseif ($averageScore -ge 80) {
Write-Host "等级: 良好" -ForegroundColor Cyan
} elseif ($averageScore -ge 60) {
Write-Host "等级: 及格" -ForegroundColor Yellow
} else {
Write-Host "等级: 不及格" -ForegroundColor Red
}
# 判断是否所有科目都及格
$allPass = ($chinese -ge 60) -and ($math -ge 60) -and ($english -ge 60)
if ($allPass) {
Write-Host "恭喜!所有科目都及格了!" -ForegroundColor Green
} else {
Write-Host "注意:有科目不及格,需要努力!" -ForegroundColor Red
}
⚠️ 重要注意事项
1. 比较运算符的特殊语法
⚠️ 常见错误:初学者常写成传统符号
# ❌ 错误写法
if ($age == 18) { } # 错误!
if ($age > 18) { } # 错误!
# ✅ 正确写法
if ($age -eq 18) { } # 正确
if ($age -gt 18) { } # 正确
2. 字符串比较默认不区分大小写
# 默认不区分大小写
"HELLO" -eq "hello" # 返回 True
# 如需区分大小写,使用 -c 前缀
"HELLO" -ceq "hello" # 返回 False
3. 除法运算的结果类型
# 整数除法可能返回小数
$result = 10 / 3 # 结果是 3.3333...,不是整数
# 如需整数除法,使用 [int] 转换或取整函数
$result = [int](10 / 3) # 3(截断)
$result = [Math]::Floor(10 / 3) # 3(向下取整)
$result = [Math]::Round(10 / 3) # 3(四舍五入)
4. 逻辑运算符的短路特性
# -and 运算符:第一个条件为 False,不会计算第二个条件
$result = $false -and (1 / 0) # 不会报错,因为第一个条件为 False
# -or 运算符:第一个条件为 True,不会计算第二个条件
$result = $true -or (1 / 0) # 不会报错,因为第一个条件为 True
5. 运算符两侧空格不影响结果
# 以下写法都是正确的
$result = 5+3 # 紧凑
$result = 5 + 3 # 推荐:有空格
$result = 5 + 3 # 多个空格(不推荐)
建议:运算符两侧加空格,提高代码可读性。
✍️ 练习任务
基础练习
-
计算练习
- 创建脚本,计算圆的面积和周长(用户输入半径)
- 提示:面积 = π × r²,周长 = 2 × π × r
- π 的值:
[Math]::PI
-
比较练习
- 让用户输入年龄
- 判断并输出:未成年(<18)、成年(18-60)、老年(>60)
-
逻辑练习
- 判断一个年份是否为闰年
- 闰年规则:能被4整除但不能被100整除,或者能被400整除
进阶练习
-
简易购物系统
- 用户输入商品单价和数量
- 根据数量计算折扣(≥10件9折,≥50件8折)
- 计算并显示小计、折扣、税额(8%)、总价
-
文件管理助手
- 获取指定目录下的所有文件
- 统计文件总数、总大小
- 筛选并显示大于指定大小的文件
-
成绩等级判定
- 用户输入三门课成绩
- 计算总分、平均分、等级
- 判断是否有不及格科目
- 输出详细的成绩报告
实战挑战
-
BMI 计算器
- 用户输入身高(米)和体重(公斤)
- 计算 BMI:体重 / (身高 × 身高)
- 判断健康状态:
- BMI < 18.5:偏瘦
- 18.5 ≤ BMI < 24:正常
- 24 ≤ BMI < 28:超重
- BMI ≥ 28:肥胖
-
密码强度检测器
- 用户输入密码
- 检测密码强度并返回评分:
- 长度 ≥ 8:+10分
- 包含大写字母:+20分
- 包含小写字母:+10分
- 包含数字:+20分
- 包含特殊字符:+30分
- 总分 ≥ 60:弱
- 总分 ≥ 80:中
- 总分 ≥ 90:强
💡 常见问题 FAQ
Q1: 为什么 PowerShell 的比较运算符不是 == 而是 -eq?
A: 这是 PowerShell 的设计选择,原因包括:
- 避免与赋值运算符
=混淆 - 统一的运算符命名规则(都以
-开头) - 更清晰的语法,易于阅读
Q2: -eq 和 -ceq 有什么区别?
A:
-eq:大小写不敏感(默认),"A" -eq "a"返回 True-ceq:大小写敏感,"A" -ceq "a"返回 False- 类似的,
-gt,-lt等都有-c前缀版本
Q3: 如何判断一个变量是否为 null?
A: 使用 $null 比较:
if ($value -eq $null) {
Write-Host "变量为空"
}
Q4: 字符串连接用 + 还是双引号更高效?
A:
- 少量连接:性能差异不大,选择更易读的方式
- 大量连接:建议使用
StringBuilder类 - 推荐使用双引号变量插值:
"$firstName $lastName"
Q5: 为什么 1/2 的结果是 0 而不是 0.5?
A: 在 PowerShell 中,整数相除会自动转换为浮点数:
$result = 1 / 2 # 结果是 0.5
$result = 1.0 / 2 # 结果也是 0.5
如果确实需要整数除法,使用 [int] 转换或取整函数。
📚 拓展阅读
推荐资源
-
官方文档
-
学习建议
- 多练习运算符的组合使用
- 注意比较运算符的特殊语法
- 熟练掌握逻辑运算符的优先级
- 使用括号明确优先级
-
下一步学习
- 条件判断语句(if, elseif, else)
- 循环结构(for, foreach, while)
- 函数的定义和调用
恭喜!你已经掌握了 PowerShell 的运算符与表达式! 🎉
这些基础知识是后续学习的基石,请务必多加练习,灵活运用!