课时4:运算符大全 —— 算术 / 赋值 / 关系 / 逻辑

一、课前热身:运算符是什么?

摘要:本文以大白话方式系统讲解 C 语言中的四大类运算符——算术运算符(含自增自减)、赋值运算符、关系运算符和逻辑运算符,并涵盖三目运算符、运算符优先级及短路特性。通过大量代码示例、运行结果和易错点分析,帮助初学者快速掌握运算符的用法与常见陷阱。文末附有综合计算器示例和课后练习。

想象一下,你有一个计算器。计算器上有哪些按键?数字键 0-9,还有 +、-、×、÷、= 这些符号。这些符号就是「运算符」,它们的作用就是让数字做各种运算。

C 语言里的运算符也是一样的作用——让变量和数据做运算。只不过 C 语言的运算符更多、更强大。

今天我们就学四类最常用的运算符:

  • 算术运算符:加减乘除、自增自减
  • 赋值运算符:把值存到变量里
  • 关系运算符:比大小,判断真假
  • 逻辑运算符:并且、或者、不是

💡 运算符是写程序的基础,就像学数学要先学加减乘除一样。今天内容有点多,但都不难,跟着例子走一遍就会了。

二、算术运算符

2.1 基本算术运算

运算符含义示例结果
+加法5 + 38
-减法5 - 32
*乘法5 * 315
/除法5 / 31(注意!整数除法)
%取余(模运算)5 % 32
#include <stdio.h>
int main() {
    int a = 10, b = 3;
    printf("a + b = %d\n", a + b);   // 13
    printf("a - b = %d\n", a - b);   // 7
    printf("a * b = %d\n", a * b);   // 30
    printf("a / b = %d\n", a / b);   // 3(整数除法,只保留整数部分)
    printf("a %% b = %d\n", a % b);   // 1(取余数,10除以3余1)
    return 0;
}

运行结果:

a + b = 13
a - b = 7
a * b = 30
a / b = 3
a % b = 1

⚠️ 重点注意:两个整数相除,结果也是整数,直接把小数部分砍掉(不是四舍五入)!5 / 3 = 1,不是 1.666,也不是 2。想要小数结果,至少有一个数是浮点数。

浮点数除法

#include <stdio.h>
int main() {
    int a = 5, b = 2;
    printf("整数除法:%d / %d = %d\n", a, b, a / b);     // 2
    printf("浮点数除法:%.1f / %d = %.2f\n", 5.0, b, 5.0 / b);  // 2.50
    return 0;
}

运行结果:

整数除法:5 / 2 = 2
浮点数除法:5.0 / 2 = 2.50

💡 取余运算符 % 只能用于整数,不能用于浮点数。它的用处很多,比如判断奇偶(x % 2 == 0 就是偶数)、找个位数、循环计数等等。

2.2 自增自减运算符(重点难点)

写程序的时候,经常需要让一个变量加 1 或者减 1。比如计数的时候,count = count + 1。C 语言提供了更简洁的写法:++--

运算符含义等价于
a++自增(后缀)a = a + 1(先用后加)
++a自增(前缀)a = a + 1(先加后用)
a–自减(后缀)a = a - 1(先用后减)
–a自减(前缀)a = a - 1(先减后用)

前缀和后缀的区别

大白话解释:

  • a++ —— 「先用再说」:先把 a 的值拿出去用,用完了再给 a 加 1
  • ++a —— 「先加再用」:先给 a 加 1,加完了再把新值拿出去用
#include <stdio.h>
int main() {
    int a = 5;
    int b;
    // 后缀自增:先用后加
    b = a++;   // 先把a的值(5)赋给b,然后a变成6
    printf("后缀:b=%d, a=%d\n", b, a);   // b=5, a=6
    // 重置a
    a = 5;
    // 前缀自增:先加后用
    b = ++a;   // 先给a加1变成6,然后把6赋给b
    printf("前缀:b=%d, a=%d\n", b, a);   // b=6, a=6
    return 0;
}

运行结果:

后缀:b=5, a=6
前缀:b=6, a=6

💡 记忆口诀:++ 在后面,就「后」加;++ 在前面,就「前」加。或者记成:谁在前谁说了算。变量在前就先用变量,++ 在前就先自增。

⚠️ 新手容易犯的错:不要在一个表达式里写好几个 a++ 或者 ++a,比如 a++ + ++a 这种。不同编译器结果可能不一样,而且代码可读性极差。写代码要清晰,不要炫技。

自增自减的常见用法

#include <stdio.h>
int main() {
    int count = 0;
    // 最常见:单独使用,前缀后缀效果一样
    count++;
    printf("count = %d\n", count);   // 1
    ++count;
    printf("count = %d\n", count);   // 2
    // 用在循环里(后面会讲循环)
    // for (int i = 0; i < 10; i++) { ... }
    return 0;
}

💡 如果只是单独写一句 a++; 或者 ++a;,那两者效果完全一样,都是让 a 加 1。只有当自增运算和其他运算混在一起的时候,才有区别。

三、赋值运算符

3.1 基本赋值

= 就是赋值运算符,作用是把右边的值存到左边的变量里。

⚠️ 注意:C 语言里的 = 不是「等于」的意思,是「赋值」的意思!等于用 ==(两个等号)。这是新手最容易搞混的,没有之一!

int a = 5;   // 把5赋值给a
a = 10;      // 把10赋值给a,原来的5被覆盖了

3.2 复合赋值运算符

如果要让变量自己和自己运算,比如 a = a + 5,可以简写为 a += 5

运算符含义等价于
+=加等于a += b → a = a + b
-=减等于a -= b → a = a - b
*=乘等于a *= b → a = a * b
/=除等于a /= b → a = a / b
%=取余等于a %= b → a = a % b
#include <stdio.h>
int main() {
    int a = 10;
    a += 5;    // 等价于 a = a + 5
    printf("a += 5 后:%d\n", a);   // 15
    a -= 3;    // 等价于 a = a - 3
    printf("a -= 3 后:%d\n", a);   // 12
    a *= 2;    // 等价于 a = a * 2
    printf("a *= 2 后:%d\n", a);   // 24
    a /= 4;    // 等价于 a = a / 4
    printf("a /= 4 后:%d\n", a);   // 6
    a %= 4;    // 等价于 a = a % 4
    printf("a %%= 4 后:%d\n", a);   // 2
    return 0;
}

运行结果:

a += 5 后:15
a -= 3 后:12
a *= 2 后:24
a /= 4 后:6
a %= 4 后:2

💡 复合赋值运算符不仅写起来简洁,编译后的执行效率也可能更高(因为只计算一次左边的地址)。推荐能用就用。

四、关系运算符

4.1 什么是关系运算?

关系运算就是「比大小」,判断两个数的关系。关系运算的结果只有两种:真(成立)或者假(不成立)。

在 C 语言里,「真」用非 0 的数表示(通常是 1),「假」用 0 表示。

运算符含义示例结果
>大于5 > 31(真)
<小于5 < 30(假)
>=大于等于5 >= 51(真)
<=小于等于5 <= 30(假)
==等于5 == 51(真)
!=不等于5 != 31(真)
#include <stdio.h>
int main() {
    int a = 5, b = 3;
    printf("%d > %d = %d\n", a, b, a > b);     // 1
    printf("%d < %d = %d\n", a, b, a < b);     // 0
    printf("%d >= %d = %d\n", a, b, a >= b);   // 1
    printf("%d <= %d = %d\n", a, b, a <= b);   // 0
    printf("%d == %d = %d\n", a, b, a == b);   // 0
    printf("%d != %d = %d\n", a, b, a != b);   // 1
    return 0;
}

运行结果:

5 > 3 = 1
5 < 3 = 0
5 >= 3 = 1
5 <= 3 = 0
5 == 3 = 0
5 != 3 = 1

⚠️ 超级重点:判断相等要用 ==(两个等号),不是 =(一个等号)!= 是赋值,== 才是判断相等。写反了程序不会报错,但逻辑完全错了,而且很难发现!

新手最容易犯的错误

// ❌ 错误写法:用了赋值号
if (a = 5) {
    // 这里永远为真!因为a=5的值是5,非0就是真
    // 而且a的值被改成了5
}
// ✅ 正确写法:用两个等号
if (a == 5) {
    // 只有a等于5的时候才会执行这里
}

💡 小技巧:判断常量和变量是否相等时,可以把常量写在左边,比如 5 == a。这样如果你不小心写成了 5 = a,编译器会直接报错,因为不能给常量赋值。这是一个防错小技巧。

五、逻辑运算符

5.1 三种逻辑运算

逻辑运算就是「并且」「或者」「不是」的意思,用来组合多个条件。

运算符含义大白话示例
&&逻辑与(并且)两边都为真,结果才为真a > 0 && a < 10
||逻辑或(或者)只要有一边为真,结果就为真a < 0 || a > 10
!逻辑非(取反)真变假,假变真!(a > 5)

逻辑与 &&(并且)

#include <stdio.h>
int main() {
    int score = 85;
    // 判断分数是否在80到90之间
    if (score >= 80 && score < 90) {
        printf("良好\n");
    }
    // 注意:不能写成 80 <= score < 90,那是数学写法,C语言里不对!
    return 0;
}

逻辑或 ||(或者)

#include <stdio.h>
int main() {
    int age = 65;
    // 判断是否是老人或小孩
    if (age < 6 || age >= 60) {
        printf("可以半价\n");
    }
    return 0;
}

逻辑非 !(取反)

#include <stdio.h>
int main() {
    int is_raining = 0;   // 0表示没下雨
    if (!is_raining) {
        printf("没下雨,出去玩吧!\n");
    }
    return 0;
}

5.2 短路特性(重点!)

逻辑运算符有一个很重要的特性:短路求值。大白话就是:如果左边已经能确定结果了,右边就不执行了。

  • && 短路:左边为假时,右边不执行(因为已经知道结果是假了)
  • || 短路:左边为真时,右边不执行(因为已经知道结果是真了)
#include <stdio.h>
int main() {
    int a = 5, b = 0;
    // && 短路:左边为假,右边不执行
    if (a > 10 && (b = 100)) {
        printf("条件成立\n");
    }
    printf("b = %d\n", b);   // b还是0,因为右边没执行
    // || 短路:左边为真,右边不执行
    a = 5;
    b = 0;
    if (a > 0 || (b = 100)) {
        printf("条件成立\n");
    }
    printf("b = %d\n", b);   // b还是0,因为右边没执行
    return 0;
}

运行结果:

b = 0
条件成立
b = 0

💡 短路特性有好有坏:好处是效率高,不用白做功;坏处是如果右边有赋值、自增等副作用,可能不会执行。写代码的时候要注意,不要把重要的操作写在逻辑运算符的右边。

六、三目运算符(条件运算符)

6.1 什么是三目运算符?

三目运算符是 C 语言里唯一的一个有三个操作数的运算符,也叫条件运算符。它可以看作是简化版的 if-else

语法:

条件 ? 表达式1 : 表达式2

执行逻辑:

  • 如果条件为真,整个表达式的值就是表达式1的值
  • 如果条件为假,整个表达式的值就是表达式2的值
#include <stdio.h>
int main() {
    int score = 75;
    char *result;
    // 用三目运算符判断是否及格
    result = (score >= 60) ? "及格" : "不及格";
    printf("分数:%d,结果:%s\n", score, result);
    // 等价于下面的if-else
    if (score >= 60) {
        result = "及格";
    } else {
        result = "不及格";
    }
    return 0;
}

运行结果:

分数:75,结果:及格

求两个数的最大值

#include <stdio.h>
int main() {
    int a = 10, b = 20;
    int max;
    // 三目运算符求最大值
    max = (a > b) ? a : b;
    printf("max = %d\n", max);   // 20
    // 也可以直接用在printf里
    printf("较大的数是:%d\n", (a > b) ? a : b);
    return 0;
}

💡 三目运算符适合简单的二选一情况,写起来很简洁。但如果逻辑复杂,还是用 if-else 更清晰。代码首先要让人看懂,不要为了炫技写复杂的三目运算。

三目运算符嵌套(了解即可)

#include <stdio.h>
int main() {
    int score = 85;
    // 嵌套三目运算符:判断优秀、良好、及格、不及格
    printf("等级:");
    printf(score >= 90 ? "优秀" : 
           score >= 80 ? "良好" : 
           score >= 60 ? "及格" : "不及格");
    printf("\n");
    return 0;
}

运行结果:

等级:良好

⚠️ 三目运算符嵌套可读性很差,不推荐使用。复杂的判断还是用 if-else if-else 更清楚。

七、运算符优先级

7.1 优先级表格

运算符有优先级,就像数学里先乘除后加减一样。C 语言里运算符很多,优先级也分好多级。不用全记住,常用的记住就行。

优先级运算符说明结合方向
1(最高)() [] -> .括号、数组、结构体成员从左到右
2! ~ ++ – + - * & sizeof单目运算符从右到左
3* / %乘、除、取余从左到右
4+ -加、减从左到右
5<< >>位移(后面讲)从左到右
6< <= > >=关系运算从左到右
7== !=等于、不等于从左到右
8&按位与从左到右
9^按位异或从左到右
10|按位或从左到右
11&&逻辑与从左到右
12||逻辑或从左到右
13?:三目运算符从右到左
14= += -= *= /= %=赋值运算符从右到左
15(最低),逗号运算符从左到右

💡 不用全背!记住几个关键的就行:括号最高,然后单目运算符,然后乘除,然后加减,然后关系,然后逻辑,最后赋值。实在不确定就加括号,括号永远是最高优先级。

7.2 优先级示例

#include <stdio.h>
int main() {
    int a = 5 + 3 * 2;       // 先乘后加:5 + 6 = 11
    printf("5 + 3 * 2 = %d\n", a);
    int b = (5 + 3) * 2;     // 括号优先:8 * 2 = 16
    printf("(5 + 3) * 2 = %d\n", b);
    int c = 10 > 5 && 3 < 4;  // 先关系,后逻辑:1 && 1 = 1
    printf("10 > 5 && 3 < 4 = %d\n", c);
    int x = 5;
    int y = -x++;            // 先++(后缀),再取负?不对!
    // 实际上:后缀++优先级比负号高,但后缀是「先用后加」
    // 所以:-x++ 等价于 -(x++),先取x的值5取负得-5,然后x变成6
    printf("y = %d, x = %d\n", y, x);   // y = -5, x = 6
    return 0;
}

运行结果:

5 + 3 * 2 = 11
(5 + 3) * 2 = 16
10 > 5 && 3 < 4 = 1
y = -5, x = 6

💡 最佳实践:不确定优先级就加括号!括号不仅能保证正确,还能让代码更清晰,别人一看就知道你的意图。代码是写给人看的,顺便给机器执行。

八、新手高频易错点

易错点1:== 和 = 搞混

// ❌ 错误:把赋值当判断
if (a = 5) {
    // 永远为真,而且a被改成5了
}
// ✅ 正确:两个等号才是判断相等
if (a == 5) {
    // 只有a等于5才执行
}

⚠️ 这是新手最最最容易犯的错误,而且编译器不报错!写完判断条件一定要检查:是不是两个等号?

易错点2:整数除法的坑

// ❌ 错误:以为会得到小数
int a = 5, b = 2;
double c = a / b;   // c = 2.0,不是2.5!
// 因为a和b都是int,先做整数除法得2,再转成double
// ✅ 正确:至少有一个是浮点数
double c = (double)a / b;   // 或者 5.0 / 2
// 先把a转成double,再做除法,结果是2.5

易错点3:自增自减搞反前后缀

int a = 5;
int b = a++;   // 后缀:先用后加
// b = 5, a = 6
int c = 5;
int d = ++c;   // 前缀:先加后用
// d = 6, c = 6

💡 记忆方法:谁在前谁说了算。变量在前就先用变量的值,++ 在前就先自增。

易错点4:逻辑运算符的短路

int a = 5, b = 0;
if (a > 10 && ++b) {  // 左边为假,右边不执行
    // ...
}
// b还是0,没有自增!
// 不要在逻辑运算符右边写有副作用的代码

易错点5:连续比较的写法

// ❌ 错误:数学写法直接搬过来
if (0 < a < 10) {
    // 这个写法语法没错,但意思不对!
    // 先算 0 < a 得0或1,再用结果和10比
    // 永远为真,因为0和1都小于10
}
// ✅ 正确:用逻辑与连接
if (a > 0 && a < 10) {
    // 这才是判断a是否在0到10之间
}

易错点6:取余运算的正负号

// 取余结果的符号和被除数相同
printf("%d\n", 5 % 3);    // 2
printf("%d\n", -5 % 3);   // -2(和被除数-5同号)
printf("%d\n", 5 % -3);   // 2(和被除数5同号)
printf("%d\n", -5 % -3);  // -2

💡 不同语言取余的规则可能不一样,C 语言里是「结果符号和被除数相同」。判断奇偶的时候要注意负数。

九、综合示例:简单计算器

学了这么多运算符,我们来写一个简单的计算器程序,把今天学的知识都用上:

#include <stdio.h>
int main() {
    double num1, num2;
    char op;
    printf("===== 简单计算器 =====\n");
    printf("请输入算式(如:5 + 3):");
    scanf("%lf %c %lf", &num1, &op, &num2);
    printf("\n计算结果:\n");
    // 用三目运算符判断并输出结果
    if (op == '+') {
        printf("%.2f + %.2f = %.2f\n", num1, num2, num1 + num2);
    } else if (op == '-') {
        printf("%.2f - %.2f = %.2f\n", num1, num2, num1 - num2);
    } else if (op == '*') {
        printf("%.2f * %.2f = %.2f\n", num1, num2, num1 * num2);
    } else if (op == '/') {
        // 判断除数是否为0
        if (num2 == 0) {
            printf("错误:除数不能为0!\n");
        } else {
            printf("%.2f / %.2f = %.2f\n", num1, num2, num1 / num2);
        }
    } else if (op == '%') {
        // 取余只能用于整数
        int n1 = (int)num1;
        int n2 = (int)num2;
        if (n2 == 0) {
            printf("错误:除数不能为0!\n");
        } else {
            printf("%d %% %d = %d\n", n1, n2, n1 % n2);
        }
    } else {
        printf("错误:不支持的运算符 %c\n", op);
    }
    // 自增自减演示
    int count = 0;
    count++;
    printf("\n运算次数:%d次\n", count);
    return 0;
}

运行示例:

===== 简单计算器 =====
请输入算式(如:5 + 3):【10 / 4】回车
计算结果:
10.00 / 4.00 = 2.50
运算次数:1次

十、课后总结

10.1 核心知识点回顾

分类运算符关键点
算术+ - * / %整数除法只保留整数,%取余只能用于整数
自增自减++ –后缀先用后加,前缀先加后用
赋值= += -= *= /= %=右边的值存到左边,复合赋值更简洁
关系> < >= <= == !=结果是0或1,==是判断,=是赋值
逻辑&& || !&&两边都真才真,||一边真就真,!取反
短路&& ||左边能确定结果时,右边不执行
三目?:条件?值1:值2,简化版if-else
优先级括号 > 单目 > 乘除 > 加减 > 关系 > 逻辑 > 赋值

10.2 六大易错点速查

  • === 搞混 —— 判断相等一定要两个等号
  • ❌ 整数除法得小数 —— 至少一个浮点数才能得到小数结果
  • ❌ 自增前后缀搞反 —— 谁在前谁说了算
  • ❌ 逻辑运算符右边有副作用 —— 可能因为短路不执行
  • ❌ 连续比较 0 < a < 10 —— 要用 && 连接
  • ❌ 取余符号搞不清 —— 结果符号和被除数相同

10.3 课后练习

  1. 写一个程序,输入两个整数,输出它们的和、差、积、商、余数
  2. 输入一个整数,判断它是奇数还是偶数(用%运算符)
  3. 用三目运算符实现:输入三个整数,输出最大值
  4. 写一段代码验证自增自减的前缀后缀区别,自己动手跑一遍
  5. 故意犯几个今天讲的易错点,看看程序会出什么问题(加深印象)

—— 课时6 结束 ——

下节课预告:选择结构 if / switch

源码链接: https://pan.quark.cn/s/fa13cd6c6c8d Chrome浏览器作为一款备受青睐的网页浏览器,凭借其出色的稳定性和运行速度获得了广泛认可。 然而出于安全考量,Chrome系统默认不兼容ActiveX插件,因为ActiveX技术主要应用于Internet Explorer,它赋予网页内容与用户本地系统交互的能力,但同时也可能引发潜在的安全隐患。 不过在某些特定工作场景下,比如在企业内部网络环境或需要与老旧应用程序整合时,可能仍需在Chrome中启用ActiveX控件。 为此我们必须掌握在Chrome浏览器下加载和运用ActiveX的方法。 首先需要明确ActiveX的本质。 ActiveX是由微软设计的一种技术框架,旨在开发可在网页环境中运行的控件,这些控件能够完成多种功能,包括视频播放、应用程序组件运行或与硬件设备通信等。 ActiveX控件多以OCX(OLE控件)格式发布。 在Chrome浏览器中启用ActiveX需要采取额外措施,因为该浏览器本身并不支持此项技术。 以下是几种常见的解决方案: 1. **应用Chrome的兼容性设置**:部分Chrome版本提供了" --enable-internal-activex"命令行参数,可通过此参数使浏览器具备加载ActiveX控件的能力。 用户可在启动Chrome时,于快捷方式的目标路径后附加该参数来激活此功能。 例如:"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --enable-internal-activex。 2. **安装第三方插件**:市面上存在一些第三方插件,例如"IE Tab"或"ActiveX Con...
标题SpringBoot与微信小程序结合的健康饮食平台研究AI更换标题第1章引言介绍健康饮食平台的研究背景、意义、国内外研究现状、论文方法及创新点。1.1研究背景与意义阐述健康饮食平台在当前社会的重要性及其市场需求。1.2国内外研究现状分析国内外健康饮食平台的发展现状及趋势。1.3研究方法及创新点概述本文采用的研究方法和技术创新点。第2章相关理论总结健康饮食、SpringBoot及微信小程序的相关理论。2.1健康饮食理论介绍健康饮食的基本原则和营养学知识。2.2SpringBoot框架阐述SpringBoot框架的特点、优势及在项目中的应用。2.3微信小程序技术介绍微信小程序的开发技术、特点及其用户群体。第3章健康饮食平台设计详细介绍健康饮食平台的设计方案,包括前端和后端设计。3.1平台架构设计给出平台的整体架构、模块划分及交互流程。3.2数据库设计介绍数据库的设计思路、表结构及数据关系。3.3前后端交互设计阐述前后端数据交互的方式、接口设计及安全性考虑。第4章微信小程序实现介绍微信小程序的具体实现过程,包括页面设计、功能实现等。4.1页面设计与布局给出微信小程序的页面设计思路、布局及交互效果。4.2功能实现与测试详细介绍微信小程序各项功能的实现过程及测试方法。4.3用户体验优化阐述如何提升微信小程序的用户体验,包括界面优化、性能优化等。第5章平台测试与优化对健康饮食平台进行测试,并根据测试结果进行优化。5.1测试环境与数据介绍测试环境、测试数据及测试方法。5.2测试结果分析从功能、性能、用户体验等方面对测试结果进行详细分析。5.3平台优化策略根据测试结果提出平台优化策略,包括代码优化、功能改进等。第6章结论与展望总结本文的研究成果,并展望未来的研究方向。6.1研究结论概括本文的主要研究结论和平台实现效果。6.2展望指出本文研究的不足之处以及未来研究的方向和改进点。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

flowHEHE

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值