475 lines
14 KiB
Go
475 lines
14 KiB
Go
/*
|
||
05-operators.go - Go 语言运算符详解
|
||
|
||
学习目标:
|
||
1. 掌握算术运算符的使用
|
||
2. 理解比较运算符的规则
|
||
3. 学会逻辑运算符的应用
|
||
4. 了解位运算符的用法
|
||
5. 掌握赋值运算符的使用
|
||
6. 理解运算符的优先级
|
||
|
||
知识点:
|
||
- 算术运算符 (+, -, *, /, %, ++, --)
|
||
- 比较运算符 (==, !=, <, <=, >, >=)
|
||
- 逻辑运算符 (&&, ||, !)
|
||
- 位运算符 (&, |, ^, <<, >>)
|
||
- 赋值运算符 (=, +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=)
|
||
- 其他运算符 (&, *, <-)
|
||
- 运算符优先级
|
||
*/
|
||
|
||
package main
|
||
|
||
import "fmt"
|
||
|
||
func main() {
|
||
fmt.Println("=== Go 语言运算符详解 ===\n")
|
||
|
||
// 演示算术运算符
|
||
demonstrateArithmeticOperators()
|
||
|
||
// 演示比较运算符
|
||
demonstrateComparisonOperators()
|
||
|
||
// 演示逻辑运算符
|
||
demonstrateLogicalOperators()
|
||
|
||
// 演示位运算符
|
||
demonstrateBitwiseOperators()
|
||
|
||
// 演示赋值运算符
|
||
demonstrateAssignmentOperators()
|
||
|
||
// 演示其他运算符
|
||
demonstrateOtherOperators()
|
||
|
||
// 演示运算符优先级
|
||
demonstrateOperatorPrecedence()
|
||
|
||
// 演示实际应用示例
|
||
demonstratePracticalExamples()
|
||
}
|
||
|
||
// demonstrateArithmeticOperators 演示算术运算符
|
||
func demonstrateArithmeticOperators() {
|
||
fmt.Println("1. 算术运算符:")
|
||
|
||
a, b := 15, 4
|
||
|
||
fmt.Printf(" 基本算术运算 (a=%d, b=%d):\n", a, b)
|
||
fmt.Printf(" a + b = %d + %d = %d\n", a, b, a+b)
|
||
fmt.Printf(" a - b = %d - %d = %d\n", a, b, a-b)
|
||
fmt.Printf(" a * b = %d * %d = %d\n", a, b, a*b)
|
||
fmt.Printf(" a / b = %d / %d = %d\n", a, b, a/b) // 整数除法
|
||
fmt.Printf(" a %% b = %d %% %d = %d\n", a, b, a%b) // 取余
|
||
|
||
// 浮点数除法
|
||
fa, fb := 15.0, 4.0
|
||
fmt.Printf(" 浮点数除法:\n")
|
||
fmt.Printf(" %.1f / %.1f = %.2f\n", fa, fb, fa/fb)
|
||
|
||
// 自增和自减运算符
|
||
fmt.Printf(" 自增和自减运算符:\n")
|
||
x := 10
|
||
fmt.Printf(" x = %d\n", x)
|
||
x++ // x = x + 1
|
||
fmt.Printf(" x++ 后: %d\n", x)
|
||
x-- // x = x - 1
|
||
fmt.Printf(" x-- 后: %d\n", x)
|
||
|
||
// 注意:Go 中的 ++ 和 -- 是语句,不是表达式
|
||
fmt.Printf(" 注意: Go 中 ++ 和 -- 是语句,不能用在表达式中\n")
|
||
// y := x++ // 编译错误
|
||
// z := ++x // 编译错误,Go 没有前置 ++
|
||
|
||
// 一元运算符
|
||
fmt.Printf(" 一元运算符:\n")
|
||
positive := +10
|
||
negative := -10
|
||
fmt.Printf(" +10 = %d\n", positive)
|
||
fmt.Printf(" -10 = %d\n", negative)
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
// demonstrateComparisonOperators 演示比较运算符
|
||
func demonstrateComparisonOperators() {
|
||
fmt.Println("2. 比较运算符:")
|
||
|
||
a, b := 10, 20
|
||
|
||
fmt.Printf(" 数值比较 (a=%d, b=%d):\n", a, b)
|
||
fmt.Printf(" a == b: %d == %d = %t\n", a, b, a == b)
|
||
fmt.Printf(" a != b: %d != %d = %t\n", a, b, a != b)
|
||
fmt.Printf(" a < b: %d < %d = %t\n", a, b, a < b)
|
||
fmt.Printf(" a <= b: %d <= %d = %t\n", a, b, a <= b)
|
||
fmt.Printf(" a > b: %d > %d = %t\n", a, b, a > b)
|
||
fmt.Printf(" a >= b: %d >= %d = %t\n", a, b, a >= b)
|
||
|
||
// 字符串比较
|
||
s1, s2 := "apple", "banana"
|
||
fmt.Printf(" 字符串比较 (s1=\"%s\", s2=\"%s\"):\n", s1, s2)
|
||
fmt.Printf(" s1 == s2: %t\n", s1 == s2)
|
||
fmt.Printf(" s1 < s2: %t (按字典序)\n", s1 < s2)
|
||
fmt.Printf(" s1 > s2: %t\n", s1 > s2)
|
||
|
||
// 布尔值比较
|
||
bool1, bool2 := true, false
|
||
fmt.Printf(" 布尔值比较:\n")
|
||
fmt.Printf(" true == false: %t\n", bool1 == bool2)
|
||
fmt.Printf(" true != false: %t\n", bool1 != bool2)
|
||
|
||
// 注意:不同类型不能直接比较
|
||
fmt.Printf(" 注意: 不同类型不能直接比较,需要类型转换\n")
|
||
var i int = 10
|
||
var f float64 = 10.0
|
||
// fmt.Println(i == f) // 编译错误
|
||
fmt.Printf(" int(10) == float64(10.0): %t\n", float64(i) == f)
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
// demonstrateLogicalOperators 演示逻辑运算符
|
||
func demonstrateLogicalOperators() {
|
||
fmt.Println("3. 逻辑运算符:")
|
||
|
||
a, b := true, false
|
||
|
||
fmt.Printf(" 基本逻辑运算 (a=%t, b=%t):\n", a, b)
|
||
fmt.Printf(" a && b: %t && %t = %t (逻辑与)\n", a, b, a && b)
|
||
fmt.Printf(" a || b: %t || %t = %t (逻辑或)\n", a, b, a || b)
|
||
fmt.Printf(" !a: !%t = %t (逻辑非)\n", a, !a)
|
||
fmt.Printf(" !b: !%t = %t\n", b, !b)
|
||
|
||
// 真值表
|
||
fmt.Printf(" 逻辑运算真值表:\n")
|
||
fmt.Printf(" A | B | A&&B | A||B | !A\n")
|
||
fmt.Printf(" ------|-------|-------|-------|------\n")
|
||
fmt.Printf(" true | true | %t | %t | %t\n", true && true, true || true, !true)
|
||
fmt.Printf(" true | false | %t| %t | %t\n", true && false, true || false, !true)
|
||
fmt.Printf(" false | true | %t| %t | %t\n", false && true, false || true, !false)
|
||
fmt.Printf(" false | false | %t| %t | %t\n", false && false, false || false, !false)
|
||
|
||
// 短路求值
|
||
fmt.Printf(" 短路求值演示:\n")
|
||
x, y := 5, 0
|
||
|
||
// && 短路:如果左边是 false,右边不会执行
|
||
fmt.Printf(" 短路与: (x > 10) && (y != 0)\n")
|
||
result1 := (x > 10) && (y != 0)
|
||
fmt.Printf(" 结果: %t (右边条件不会被检查)\n", result1)
|
||
|
||
// || 短路:如果左边是 true,右边不会执行
|
||
fmt.Printf(" 短路或: (x > 0) || (y != 0)\n")
|
||
result2 := (x > 0) || (y != 0)
|
||
fmt.Printf(" 结果: %t (右边条件不会被检查)\n", result2)
|
||
|
||
// 复合逻辑表达式
|
||
age := 25
|
||
hasLicense := true
|
||
hasInsurance := false
|
||
|
||
canDrive := age >= 18 && hasLicense && hasInsurance
|
||
fmt.Printf(" 复合条件判断:\n")
|
||
fmt.Printf(" 年龄: %d, 有驾照: %t, 有保险: %t\n", age, hasLicense, hasInsurance)
|
||
fmt.Printf(" 可以开车: %t\n", canDrive)
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
// demonstrateBitwiseOperators 演示位运算符
|
||
func demonstrateBitwiseOperators() {
|
||
fmt.Println("4. 位运算符:")
|
||
|
||
a, b := 12, 10 // 12 = 1100, 10 = 1010 (二进制)
|
||
|
||
fmt.Printf(" 位运算 (a=%d, b=%d):\n", a, b)
|
||
fmt.Printf(" a 的二进制: %08b\n", a)
|
||
fmt.Printf(" b 的二进制: %08b\n", b)
|
||
fmt.Printf(" a & b: %08b = %d (按位与)\n", a & b, a & b)
|
||
fmt.Printf(" a | b: %08b = %d (按位或)\n", a | b, a | b)
|
||
fmt.Printf(" a ^ b: %08b = %d (按位异或)\n", a ^ b, a ^ b)
|
||
fmt.Printf(" ^a: %08b = %d (按位取反)\n", ^a, ^a)
|
||
|
||
// 位移运算
|
||
fmt.Printf(" 位移运算:\n")
|
||
x := 8 // 1000 (二进制)
|
||
fmt.Printf(" x = %d (%08b)\n", x, x)
|
||
fmt.Printf(" x << 1: %08b = %d (左移1位)\n", x << 1, x << 1)
|
||
fmt.Printf(" x << 2: %08b = %d (左移2位)\n", x << 2, x << 2)
|
||
fmt.Printf(" x >> 1: %08b = %d (右移1位)\n", x >> 1, x >> 1)
|
||
fmt.Printf(" x >> 2: %08b = %d (右移2位)\n", x >> 2, x >> 2)
|
||
|
||
// 位运算的实际应用
|
||
fmt.Printf(" 位运算应用示例:\n")
|
||
|
||
// 检查奇偶性
|
||
num := 15
|
||
isEven := (num & 1) == 0
|
||
fmt.Printf(" %d 是偶数: %t (使用 n&1==0 检查)\n", num, isEven)
|
||
|
||
// 快速乘除法(2的幂)
|
||
fmt.Printf(" 快速乘除法:\n")
|
||
fmt.Printf(" %d * 4 = %d << 2 = %d\n", num, num, num << 2)
|
||
fmt.Printf(" %d / 4 = %d >> 2 = %d\n", num, num, num >> 2)
|
||
|
||
// 设置、清除、切换位
|
||
flags := 0
|
||
fmt.Printf(" 位标志操作:\n")
|
||
fmt.Printf(" 初始标志: %08b\n", flags)
|
||
|
||
flags |= (1 << 2) // 设置第2位
|
||
fmt.Printf(" 设置第2位: %08b\n", flags)
|
||
|
||
flags &^= (1 << 2) // 清除第2位
|
||
fmt.Printf(" 清除第2位: %08b\n", flags)
|
||
|
||
flags ^= (1 << 1) // 切换第1位
|
||
fmt.Printf(" 切换第1位: %08b\n", flags)
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
// demonstrateAssignmentOperators 演示赋值运算符
|
||
func demonstrateAssignmentOperators() {
|
||
fmt.Println("5. 赋值运算符:")
|
||
|
||
// 基本赋值
|
||
var x int = 10
|
||
fmt.Printf(" 基本赋值: x = %d\n", x)
|
||
|
||
// 复合赋值运算符
|
||
fmt.Printf(" 复合赋值运算符:\n")
|
||
|
||
x += 5 // x = x + 5
|
||
fmt.Printf(" x += 5: x = %d\n", x)
|
||
|
||
x -= 3 // x = x - 3
|
||
fmt.Printf(" x -= 3: x = %d\n", x)
|
||
|
||
x *= 2 // x = x * 2
|
||
fmt.Printf(" x *= 2: x = %d\n", x)
|
||
|
||
x /= 4 // x = x / 4
|
||
fmt.Printf(" x /= 4: x = %d\n", x)
|
||
|
||
x %= 3 // x = x % 3
|
||
fmt.Printf(" x %%= 3: x = %d\n", x)
|
||
|
||
// 位运算赋值
|
||
fmt.Printf(" 位运算赋值:\n")
|
||
y := 12 // 1100
|
||
fmt.Printf(" y = %d (%04b)\n", y, y)
|
||
|
||
y &= 10 // y = y & 10 (1010)
|
||
fmt.Printf(" y &= 10: y = %d (%04b)\n", y, y)
|
||
|
||
y |= 5 // y = y | 5 (0101)
|
||
fmt.Printf(" y |= 5: y = %d (%04b)\n", y, y)
|
||
|
||
y ^= 3 // y = y ^ 3 (0011)
|
||
fmt.Printf(" y ^= 3: y = %d (%04b)\n", y, y)
|
||
|
||
y <<= 1 // y = y << 1
|
||
fmt.Printf(" y <<= 1: y = %d (%04b)\n", y, y)
|
||
|
||
y >>= 2 // y = y >> 2
|
||
fmt.Printf(" y >>= 2: y = %d (%04b)\n", y, y)
|
||
|
||
// 多重赋值
|
||
fmt.Printf(" 多重赋值:\n")
|
||
a, b, c := 1, 2, 3
|
||
fmt.Printf(" a, b, c := 1, 2, 3: a=%d, b=%d, c=%d\n", a, b, c)
|
||
|
||
// 交换变量
|
||
a, b = b, a
|
||
fmt.Printf(" a, b = b, a: a=%d, b=%d (交换)\n", a, b)
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
// demonstrateOtherOperators 演示其他运算符
|
||
func demonstrateOtherOperators() {
|
||
fmt.Println("6. 其他运算符:")
|
||
|
||
// 地址运算符 &
|
||
x := 42
|
||
ptr := &x
|
||
fmt.Printf(" 地址运算符 &:\n")
|
||
fmt.Printf(" x = %d\n", x)
|
||
fmt.Printf(" &x = %p (x的地址)\n", ptr)
|
||
|
||
// 解引用运算符 *
|
||
fmt.Printf(" 解引用运算符 *:\n")
|
||
fmt.Printf(" *ptr = %d (ptr指向的值)\n", *ptr)
|
||
|
||
// 修改指针指向的值
|
||
*ptr = 100
|
||
fmt.Printf(" 修改 *ptr = 100 后, x = %d\n", x)
|
||
|
||
// 通道运算符 <- (这里只是语法演示,详细内容在并发章节)
|
||
fmt.Printf(" 通道运算符 <- (语法演示):\n")
|
||
ch := make(chan int, 1)
|
||
ch <- 42 // 发送值到通道
|
||
value := <-ch // 从通道接收值
|
||
fmt.Printf(" 通道发送和接收: %d\n", value)
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
// demonstrateOperatorPrecedence 演示运算符优先级
|
||
func demonstrateOperatorPrecedence() {
|
||
fmt.Println("7. 运算符优先级:")
|
||
|
||
// 算术运算符优先级
|
||
result1 := 2 + 3 * 4
|
||
result2 := (2 + 3) * 4
|
||
fmt.Printf(" 算术运算优先级:\n")
|
||
fmt.Printf(" 2 + 3 * 4 = %d (乘法优先)\n", result1)
|
||
fmt.Printf(" (2 + 3) * 4 = %d (括号改变优先级)\n", result2)
|
||
|
||
// 比较和逻辑运算符优先级
|
||
a, b, c := 5, 10, 15
|
||
result3 := a < b && b < c
|
||
result4 := a < b || b > c && c > a
|
||
fmt.Printf(" 比较和逻辑运算优先级:\n")
|
||
fmt.Printf(" %d < %d && %d < %d = %t\n", a, b, b, c, result3)
|
||
fmt.Printf(" %d < %d || %d > %d && %d > %d = %t\n", a, b, b, c, c, a, result4)
|
||
|
||
// 位运算符优先级
|
||
x := 6 // 110
|
||
y := 3 // 011
|
||
result5 := x & y | x ^ y
|
||
result6 := x & (y | x) ^ y
|
||
fmt.Printf(" 位运算优先级:\n")
|
||
fmt.Printf(" %d & %d | %d ^ %d = %d\n", x, y, x, y, result5)
|
||
fmt.Printf(" %d & (%d | %d) ^ %d = %d\n", x, y, x, y, result6)
|
||
|
||
// 运算符优先级表(从高到低)
|
||
fmt.Printf(" 运算符优先级表(从高到低):\n")
|
||
fmt.Printf(" 1. * / %% << >> & &^\n")
|
||
fmt.Printf(" 2. + - | ^\n")
|
||
fmt.Printf(" 3. == != < <= > >=\n")
|
||
fmt.Printf(" 4. &&\n")
|
||
fmt.Printf(" 5. ||\n")
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
// demonstratePracticalExamples 演示实际应用示例
|
||
func demonstratePracticalExamples() {
|
||
fmt.Println("8. 实际应用示例:")
|
||
|
||
// 示例1: 计算器功能
|
||
fmt.Printf(" 示例1 - 简单计算器:\n")
|
||
num1, num2 := 15.5, 4.2
|
||
operator := "+"
|
||
|
||
var result float64
|
||
switch operator {
|
||
case "+":
|
||
result = num1 + num2
|
||
case "-":
|
||
result = num1 - num2
|
||
case "*":
|
||
result = num1 * num2
|
||
case "/":
|
||
if num2 != 0 {
|
||
result = num1 / num2
|
||
} else {
|
||
fmt.Printf(" 错误: 除数不能为零\n")
|
||
return
|
||
}
|
||
}
|
||
fmt.Printf(" %.1f %s %.1f = %.2f\n", num1, operator, num2, result)
|
||
|
||
// 示例2: 判断闰年
|
||
fmt.Printf(" 示例2 - 判断闰年:\n")
|
||
year := 2024
|
||
isLeapYear := (year%4 == 0 && year%100 != 0) || (year%400 == 0)
|
||
fmt.Printf(" %d年是闰年: %t\n", year, isLeapYear)
|
||
|
||
// 示例3: 位掩码操作
|
||
fmt.Printf(" 示例3 - 权限系统 (位掩码):\n")
|
||
const (
|
||
READ = 1 << 0 // 001
|
||
WRITE = 1 << 1 // 010
|
||
EXECUTE = 1 << 2 // 100
|
||
)
|
||
|
||
// 设置权限
|
||
permissions := READ | WRITE // 011
|
||
fmt.Printf(" 初始权限: %03b (读:%t, 写:%t, 执行:%t)\n",
|
||
permissions,
|
||
permissions&READ != 0,
|
||
permissions&WRITE != 0,
|
||
permissions&EXECUTE != 0)
|
||
|
||
// 添加执行权限
|
||
permissions |= EXECUTE // 111
|
||
fmt.Printf(" 添加执行权限: %03b (读:%t, 写:%t, 执行:%t)\n",
|
||
permissions,
|
||
permissions&READ != 0,
|
||
permissions&WRITE != 0,
|
||
permissions&EXECUTE != 0)
|
||
|
||
// 移除写权限
|
||
permissions &^= WRITE // 101
|
||
fmt.Printf(" 移除写权限: %03b (读:%t, 写:%t, 执行:%t)\n",
|
||
permissions,
|
||
permissions&READ != 0,
|
||
permissions&WRITE != 0,
|
||
permissions&EXECUTE != 0)
|
||
|
||
// 示例4: 条件表达式模拟
|
||
fmt.Printf(" 示例4 - 条件表达式模拟:\n")
|
||
score := 85
|
||
var grade string
|
||
|
||
// Go 没有三元运算符,使用 if-else
|
||
if score >= 90 {
|
||
grade = "A"
|
||
} else if score >= 80 {
|
||
grade = "B"
|
||
} else if score >= 70 {
|
||
grade = "C"
|
||
} else if score >= 60 {
|
||
grade = "D"
|
||
} else {
|
||
grade = "F"
|
||
}
|
||
|
||
fmt.Printf(" 分数 %d 对应等级: %s\n", score, grade)
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
/*
|
||
运行这个程序:
|
||
go run 05-operators.go
|
||
|
||
学习要点:
|
||
1. Go 支持丰富的运算符,包括算术、比较、逻辑、位运算等
|
||
2. ++ 和 -- 在 Go 中是语句,不是表达式,不能用在赋值中
|
||
3. Go 不支持隐式类型转换,不同类型不能直接比较或运算
|
||
4. 逻辑运算符支持短路求值,可以提高效率和安全性
|
||
5. 位运算符在系统编程和性能优化中很有用
|
||
6. 复合赋值运算符可以简化代码
|
||
7. 运算符有优先级,使用括号可以改变优先级
|
||
8. Go 没有三元运算符,使用 if-else 代替
|
||
|
||
实际应用:
|
||
1. 算术运算符用于数学计算
|
||
2. 比较运算符用于条件判断
|
||
3. 逻辑运算符用于复合条件
|
||
4. 位运算符用于标志位操作、权限系统等
|
||
5. 赋值运算符用于变量更新
|
||
|
||
注意事项:
|
||
1. 除法运算要注意整数除法和浮点除法的区别
|
||
2. 取余运算的结果符号与被除数相同
|
||
3. 位运算时要注意数据类型的位数
|
||
4. 使用逻辑运算符时要注意短路求值的特性
|
||
5. 复杂表达式建议使用括号明确优先级
|
||
*/ |