3.1 什么是运算符和表达式?

3.1.1 基本概念

运算符:告诉计算机要对数据做什么操作(比如加法、比较、赋值)
表达式:由运算符和操作数组成的式子(比如 a + b

csharp

int a = 5;
int b = 3;
int sum = a + b;  // a + b 是表达式,+ 是运算符,a 和 b 是操作数

3.1.2 C# 运算符分类总览

分类 运算符 优先级 结合性
算术运算符 + - * / % ++ -- 从左到右
赋值运算符 = += -= *= /= %= 从右到左
比较运算符 == != > < >= <= 从左到右
逻辑运算符 && || ! 从左到右
位运算符 & | ^ ~ << >> 从左到右
条件运算符 ? : 从右到左
其他 typeof sizeof is as ?? 各异 各异

本章重点学习:算术、赋值、比较、逻辑运算符,这些是日常最常用的。


3.2 算术运算符(做数学计算)

3.2.1 基本算术运算符

运算符 名称 示例 结果
+ 加法 5 + 3 8
- 减法 5 - 3 2
* 乘法 5 * 3 15
/ 除法 5 / 2 2(整数除法)
% 取余(模运算) 5 % 2 1

3.2.2 加法运算符 +

csharp

// 数值加法
int a = 10 + 5;        // 15
double b = 3.14 + 2.86; // 6.0

// 字符串拼接(当其中一个操作数是字符串时)
string name = "张" + "三";     // "张三"
string message = "年龄:" + 25; // "年龄:25"

// 注意:从左到右执行,类型决定行为
int result1 = 1 + 2 + "3";     // "33"(先1+2=3,再拼"3")
string result2 = "1" + 2 + 3;   // "123"(字符串开头,全部变拼接)
int result3 = 1 + 2 + int.Parse("3"); // 6(全部数值计算)

3.2.3 减法运算符 -

csharp

int x = 20 - 5;        // 15
double y = 10.5 - 3.2; // 7.3

// 负号用法
int negative = -10;    // 负10
int positive = -(-10); // 10(负负得正)

3.2.4 乘法运算符 *

csharp

int area = 5 * 4;          // 20
double product = 2.5 * 4;  // 10.0

// 连续运算
int result = 2 * 3 * 4;    // 24

3.2.5 除法运算符 /(重点!重点!重点!)

这是初学者最容易出错的地方!

csharp

// 整数除法:结果只保留整数部分(截断,不是四舍五入)
int a = 10 / 3;    // 结果:3(不是 3.333...)
int b = 5 / 2;     // 结果:2(不是 2.5)
int c = 1 / 2;     // 结果:0(不是 0.5)

// 浮点数除法:得到小数结果
double d = 10.0 / 3;   // 3.33333333333333
double e = 5.0 / 2;    // 2.5
double f = 1.0 / 2;    // 0.5

// 混合类型:只要有一个是浮点数,结果就是浮点数
double g = 10 / 3.0;   // 3.333...
double h = 10.0 / 3;   // 3.333...
double i = (double)10 / 3; // 3.333...(强制转换)

// 特别注意
int total = 7;
int count = 2;
double average = total / count;     // 结果:3.0(不是 3.5!)
double correctAvg = (double)total / count; // 3.5 ✅

记忆口诀

整数除整数,结果还是整数,小数部分直接扔。

3.2.6 取余运算符 %(模运算)

取余 = 除法后的余数

csharp

int result1 = 10 % 3;   // 1(10 ÷ 3 = 3 余 1)
int result2 = 15 % 4;   // 3(15 ÷ 4 = 3 余 3)
int result3 = 20 % 5;   // 0(整除)
int result4 = 7 % 10;   // 7(7 ÷ 10 = 0 余 7)

// 判断奇偶数
bool isEven = number % 2 == 0;  // 偶数
bool isOdd = number % 2 == 1;   // 奇数

// 判断能否整除
bool isDivisible = a % b == 0;

// 获取数字的个位数
int num = 123;
int lastDigit = num % 10;  // 3

// 获取数字的十位数
int tensDigit = (num / 10) % 10;  // 2

3.2.7 自增自减运算符 ++ --

自增:变量加1;自减:变量减1

csharp

int count = 5;

// 后置自增:先使用变量的值,再自增
int a = count++;   // a = 5, count = 6

// 前置自增:先自增,再使用
int b = ++count;   // count 现在是 7,然后 b = 7

// 同理,自减
int x = 10;
int y = x--;       // y = 10, x = 9
int z = --x;       // x 变成 8,z = 8

前置 vs 后置对比表

代码 等效步骤 结果
int b = ++a; a = a + 1; b = a; a 和 b 都自增后的值
int b = a++; b = a; a = a + 1; b 是旧值,a 是新值

实际应用场景

csharp

// 循环计数器(最常见,第四章详细讲)
for (int i = 0; i < 10; i++)  // 后置自增
{
    // 循环体
}

// 独立使用时,前后置没有区别
int counter = 0;
counter++;  // 推荐写法
++counter;  // 效果一样

建议:独立使用时尽量用 counter++,简洁明了。


3.3 赋值运算符

3.3.1 简单赋值 =

把右边的值赋给左边的变量

csharp

int x = 5;      // 把 5 赋给 x
string name = "张三";

// 链式赋值(从右向左执行)
int a, b, c;
a = b = c = 10; // 相当于 c=10; b=c; a=b;

3.3.2 复合赋值运算符

对变量自身进行运算的简写

运算符 全写 示例 效果
+= a = a + b a += 5 a = a + 5
-= a = a - b a -= 3 a = a - 3
*= a = a * b a *= 2 a = a * 2
/= a = a / b a /= 4 a = a / 4
%= a = a % b a %= 3 a = a % 3

csharp

int score = 100;
score += 10;        // score = 110
score -= 20;        // score = 90
score *= 2;         // score = 180
score /= 3;         // score = 60
score %= 7;         // score = 4(60 % 7 = 4)

// 字符串也有 +=
string message = "Hello";
message += " World";  // "Hello World"

3.4 比较运算符(关系运算符)

比较两个值,返回 bool 类型(true 或 false)

运算符 名称 示例 结果
== 等于 5 == 5 true
!= 不等于 5 != 3 true
> 大于 5 > 3 true
< 小于 5 < 3 false
>= 大于等于 5 >= 5 true
<= 小于等于 5 <= 3 false

csharp

int age = 18;

bool isAdult = age >= 18;        // true
bool isTeenager = age > 12 && age < 20;  // true
bool isEqual = age == 18;        // true
bool isNotEqual = age != 18;     // false

// 注意:== 和 = 的区别
if (age = 18)  // ❌ 编译错误!= 是赋值,== 才是比较
if (age == 18) // ✅ 正确

// 比较浮点数时注意精度问题
double x = 0.1 + 0.2;
double y = 0.3;
bool equal = x == y;  // false!(因为 0.1+0.2 不等于 0.3 精确值)
bool nearlyEqual = Math.Abs(x - y) < 0.000001; // true ✅

3.5 逻辑运算符

处理布尔值之间的逻辑关系

运算符 名称 示例 结果
&& 逻辑与(AND) true && true true
|| 逻辑或(OR) true || false true
! 逻辑非(NOT) !true false

3.5.1 逻辑与 &&

所有条件都为 true,结果才为 true

csharp

bool hasID = true;
bool hasTicket = true;
bool canEnter = hasID && hasTicket;  // true

// 真值表
true && true   = true
true && false  = false
false && true  = false
false && false = false

// 实际应用:判断某数是否在范围内
int score = 85;
bool isBGrade = score >= 80 && score < 90;  // true

3.5.2 逻辑或 ||

只要有一个条件为 true,结果就为 true

csharp

bool isWeekend = true;
bool isHoliday = false;
bool canSleepIn = isWeekend || isHoliday;  // true

// 真值表
true || true   = true
true || false  = true
false || true  = true
false || false = false

// 实际应用
bool isVowel = c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u';

3.5.3 逻辑非 !

取反

csharp

bool isRaining = true;
bool isGoodWeather = !isRaining;  // false

bool isLoggedIn = false;
bool needLogin = !isLoggedIn;     // true

3.5.4 短路求值(重要!)

&& 和 || 会"偷懒":如果能提前确定结果,后面的表达式不会执行

csharp

// && 短路:第一个是 false,后面的就不看了
int a = 10;
bool result = (a > 20) && (++a > 5);  // (false) && (anything) = false
Console.WriteLine(a);  // 还是 10,++a 没有执行!

// || 短路:第一个是 true,后面的就不看了
int b = 10;
bool result2 = (b < 20) || (++b > 5);  // (true) || (anything) = true
Console.WriteLine(b);  // 还是 10,++b 没有执行!

// 如果没有短路,可能会出问题
string name = null;
// if (name.Length > 0 && name != null)  // ❌ 会报错!先判断 Length 会空引用
if (name != null && name.Length > 0)  // ✅ 先判断 null,安全
{
    Console.WriteLine("有名字");
}

3.5.5 逻辑运算符优先级

text

! (最高)
&&
|| (最低)

csharp

// 示例
bool result = true || false && false;
// 相当于 true || (false && false)
// = true || false
// = true

// 使用括号明确优先级
bool result2 = (true || false) && false;  // false

3.6 运算符优先级

当表达式中有多个运算符时,优先级决定了谁先计算

完整优先级表(从高到低)

优先级 运算符 说明
1 () 括号(最高优先级)
2 ++ --(前置) + -(正负) ! ~ 一元运算符
3 * / % 乘除取余
4 + - 加减
5 << >> 移位
6 < > <= >= 比较
7 == != 等于/不等于
8 && 逻辑与
9 || 逻辑或
10 = += -= ... 赋值(最低)

优先级示例

csharp

// 数学规则
int result = 5 + 3 * 2;   // 11(先乘后加)

// 用括号改变优先级
int result2 = (5 + 3) * 2; // 16

// 混合运算
bool result3 = 5 + 3 > 2 * 3;  
// 步骤:5+3=8,2*3=6,8>6=true

// 复杂示例
bool result4 = !true && false || 5 > 3;
// 步骤1:!true = false
// 步骤2:false && false = false
// 步骤3:5>3 = true
// 步骤4:false || true = true

黄金法则:不确定优先级就用括号 (),既清晰又安全。


3.7 其他常用运算符

3.7.1 条件运算符 ? :(三元运算符)

根据条件返回两个值之一

csharp

// 语法:条件 ? 为真时的值 : 为假时的值
int age = 18;
string status = age >= 18 ? "成年人" : "未成年人";

// 等效于 if-else(第四章讲)
string status2;
if (age >= 18)
{
    status2 = "成年人";
}
else
{
    status2 = "未成年人";
}

// 嵌套使用(不推荐过度嵌套)
int score = 85;
string grade = score >= 90 ? "A" : score >= 80 ? "B" : score >= 70 ? "C" : "D";

3.7.2 空合并运算符 ??

如果左边为 null,返回右边;否则返回左边

csharp

string name = null;
string displayName = name ?? "匿名用户";  // "匿名用户"

string nickName = "小明";
string display = nickName ?? "匿名用户";  // "小明"

// 等价写法
string result = (name != null) ? name : "匿名用户";

3.7.3 typeof 和 sizeof

csharp

// typeof:获取类型的 System.Type 对象
Type intType = typeof(int);
Console.WriteLine(intType.Name);  // "Int32"

// sizeof:获取类型占用内存大小(字节)
int byteSize = sizeof(int);     // 4
int longSize = sizeof(long);    // 8
int charSize = sizeof(char);    // 2

3.7.4 is 运算符

检查对象是否是指定类型

csharp

object obj = "Hello";
bool isString = obj is string;    // true
bool isInt = obj is int;          // false

3.8 类型转换与运算符(回顾与深入)

3.8.1 隐式转换在表达式中的发生

csharp

int a = 10;
double b = 3.5;
double c = a + b;  // a 自动转为 double,结果是 double

byte small = 100;
int bigger = small + 1000;  // small 自动转为 int

3.8.2 溢出检查运算符 checked / unchecked

csharp

// 默认情况下,整数溢出不会报错
int max = 2147483647;
int overflow = max + 1;  // -2147483648(悄悄溢出)

// checked 检测溢出,会抛异常
checked
{
    int willError = max + 1;  // OverflowException
}

// unchecked 明确允许溢出(默认行为)
unchecked
{
    int allowOverflow = max + 1;  // -2147483648
}

3.9 综合示例

示例1:计算器(支持多种运算)

csharp

using System;

Console.WriteLine("=== 简单计算器 ===");

Console.Write("请输入第一个数字:");
double num1 = Convert.ToDouble(Console.ReadLine());

Console.Write("请输入运算符(+、-、*、/、%):");
string op = Console.ReadLine();

Console.Write("请输入第二个数字:");
double num2 = Convert.ToDouble(Console.ReadLine());

double result = 0;
bool isValid = true;

// 使用条件运算符
string opName = op == "+" ? "加法" :
                op == "-" ? "减法" :
                op == "*" ? "乘法" :
                op == "/" ? "除法" :
                op == "%" ? "取余" : "未知";

if (op == "+")
{
    result = num1 + num2;
}
else if (op == "-")
{
    result = num1 - num2;
}
else if (op == "*")
{
    result = num1 * num2;
}
else if (op == "/")
{
    if (num2 != 0)
    {
        result = num1 / num2;
    }
    else
    {
        Console.WriteLine("错误:除数不能为0!");
        isValid = false;
    }
}
else if (op == "%")
{
    if (num2 != 0)
    {
        result = num1 % num2;
    }
    else
    {
        Console.WriteLine("错误:取余的除数不能为0!");
        isValid = false;
    }
}
else
{
    Console.WriteLine("错误:不支持的运算符!");
    isValid = false;
}

if (isValid)
{
    string equation = $"{num1} {op} {num2} = {result}";
    Console.WriteLine($"\n{opName}结果:{equation}");
}

示例2:判断闰年

csharp

using System;

Console.Write("请输入年份:");
int year = Convert.ToInt32(Console.ReadLine());

// 闰年规则:能被4整除但不能被100整除,或者能被400整除
bool isLeapYear = (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);

string result = isLeapYear ? "是闰年" : "不是闰年";
Console.WriteLine($"{year}年{result}");

// 附加信息
int days = isLeapYear ? 366 : 365;
Console.WriteLine($"{year}年共有{days}天");

示例3:数字特性检测

csharp

using System;

Console.Write("请输入一个整数:");
int num = Convert.ToInt32(Console.ReadLine());

bool isPositive = num > 0;
bool isNegative = num < 0;
bool isZero = num == 0;
bool isEven = num % 2 == 0;
bool isOdd = num % 2 != 0;
bool isDivisibleBy3 = num % 3 == 0;
bool isDivisibleBy5 = num % 5 == 0;
bool isDivisibleBy3And5 = isDivisibleBy3 && isDivisibleBy5;

Console.WriteLine($"\n数字 {num} 的特性:");
Console.WriteLine($"正数:{isPositive}");
Console.WriteLine($"负数:{isNegative}");
Console.WriteLine($"零:{isZero}");
Console.WriteLine($"偶数:{isEven}");
Console.WriteLine($"奇数:{isOdd}");
Console.WriteLine($"能被3整除:{isDivisibleBy3}");
Console.WriteLine($"能被5整除:{isDivisibleBy5}");
Console.WriteLine($"能被15整除:{isDivisibleBy3And5}");

3.10 常见错误与陷阱

错误1:= 和 == 混淆

csharp

if (x = 5)  // ❌ 赋值表达式,结果是5,不是bool,编译错误
if (x == 5) // ✅ 正确

错误2:整数除法陷阱

csharp

double avg = sum / count;  // 如果 sum 和 count 都是 int,结果错误
double avg = (double)sum / count;  // ✅ 正确

错误3:浮点数比较

csharp

double x = 0.1 + 0.2;
if (x == 0.3)  // false!
if (Math.Abs(x - 0.3) < 0.0000001)  // ✅ 正确

错误4:除法除以零

csharp

int x = 10 / 0;    // 抛出 DivideByZeroException
double y = 10.0 / 0;  // Infinity(不抛异常,但要注意)

错误5:短路求值误用

csharp

int i = 0;
if (i != 0 && 10 / i > 5)  // 安全,因为 i != 0 是 false,后面不执行
{
    // 不会进入
}
if (10 / i > 5 && i != 0)  // ❌ 危险!先判断 10/0 直接崩

错误6:运算符优先级误解

csharp

bool result = a > b && c > d;  // 实际上是 (a > b) && (c > d)
bool result2 = a > b || c > d; // (a > b) || (c > d) ✅ 没问题

int x = 5 + 3 * 2;  // 11,不是16
int y = (5 + 3) * 2; // 16

3.11 本章总结

核心知识导图

text

运算符
├── 算术运算符:+ - * / % ++ --
├── 赋值运算符:= += -= *= /= %=
├── 比较运算符:== != > < >= <=
├── 逻辑运算符:&& || !
└── 其他:? : ?? typeof sizeof is

优先级速记口诀

括号最优先,单目高于乘除,乘除高于加减,比较高于逻辑,赋值最后做。

类型转换要点

场景 方法
小转大(安全) 隐式转换自动
大转小(可能丢数据) 强制转换 (类型)
字符串转数字 Convert.ToInt32() 或 int.Parse()
数字转字符串 .ToString() 或 Convert.ToString()
安全转换(不抛异常) int.TryParse()

3.12 练习题

基础题

  1. 计算下列表达式的值(写出计算步骤):

    • 15 + 3 * 2

    • (15 + 3) * 2

    • 20 / 4 * 2

    • 20 / (4 * 2)

    • 17 % 5

    • 7 + 3 > 5 && 2 * 3 == 6

  2. 写出程序的输出:

csharp

int a = 10;
int b = a++;
int c = ++a;
Console.WriteLine($"a={a}, b={b}, c={c}");
  1. 判断以下哪些变量名是合法的:

    • int 1stPlace;

    • double my-score;

    • bool _isValid;

    • string class;

    • int 中国;

应用题

  1. 编写程序,输入一个三位数,输出它的:

    • 各位数字之和

    • 是否是回文数(如 121、454)

    • 提示:用 / 和 % 获取各位数字

  2. 编写程序,输入两个整数和一个运算符(+、-、*、/),输出计算结果。注意判断除数为0的情况。

  3. 编写程序,判断一个数字:

    • 是否是质数(简单的质数判断,用 % 检查是否能被2到平方根之间的数整除)

    • 提示:质数是指大于1且只能被1和自身整除

挑战题

  1. 在不使用 Math.Pow 的情况下,计算一个整数的三次方,并使用复合赋值运算符验证结果。

  2. 使用条件运算符 ?:,实现一个简单的"成绩评级"程序:

    • 90分以上:A

    • 80-89分:B

    • 70-79分:C

    • 60-69分:D

    • 60分以下:F

  3. 模拟一个简单的"找零程序":

    • 输入商品价格和付款金额

    • 输出应找零金额

    • 输出最少需要多少张纸币(100、50、20、10、5、1元)

更多推荐