运算符与表达式

数据的操作

运算符是程序中进行各种操作的符号,表达式是由运算符和操作数组成的式子。东巴文(db-w.cn) 将带你深入理解C语言的运算符和表达式,掌握数据操作的核心技能。

💡 东巴文观点:运算符是程序的工具,表达式是程序的句子。掌握运算符和表达式,才能编写出功能强大的程序。

运算符分类

C语言运算符体系

东巴文运算符分类图

C语言运算符
├── 算术运算符
│   ├── + (加)
│   ├── - (减)
│   ├── * (乘)
│   ├── / (除)
│   └── % (取模)
├── 关系运算符
│   ├── == (等于)
│   ├── != (不等于)
│   ├── > (大于)
│   ├── < (小于)
│   ├── >= (大于等于)
│   └── <= (小于等于)
├── 逻辑运算符
│   ├── && (逻辑与)
│   ├── || (逻辑或)
│   └── ! (逻辑非)
├── 位运算符
│   ├── & (按位与)
│   ├── | (按位或)
│   ├── ^ (按位异或)
│   ├── ~ (按位取反)
│   ├── << (左移)
│   └── >> (右移)
├── 赋值运算符
│   ├── = (赋值)
│   ├── += (加赋值)
│   ├── -= (减赋值)
│   ├── *= (乘赋值)
│   ├── /= (除赋值)
│   └── %= (模赋值)
├── 条件运算符
│   └── ? : (三目运算符)
├── 逗号运算符
│   └── , (逗号)
├── 指针运算符
│   ├── & (取地址)
│   └── * (解引用)
├── 求字节数运算符
│   └── sizeof
├── 下标运算符
│   └── []
├── 成员运算符
│   ├── . (结构体成员)
│   └── -> (指针成员)
└── 其他运算符
    ├── () (函数调用)
    ├── () (强制类型转换)
    └── -> (指向成员)

算术运算符

基本算术运算

东巴文算术运算符表

运算符 名称 示例 结果 东巴文说明
+ 加法 5 + 3 8 加法运算
- 减法 5 - 3 2 减法运算
* 乘法 5 * 3 15 乘法运算
/ 除法 5 / 3 1 整数除法取整
% 取模 5 % 3 2 求余数

示例代码

#include <stdio.h>

int main() {
    int a = 10, b = 3;
    
    printf("=== 东巴文算术运算示例 ===\n\n");
    printf("a = %d, b = %d\n\n", a, b);
    
    printf("加法:%d + %d = %d\n", a, b, a + b);
    printf("减法:%d - %d = %d\n", a, b, a - b);
    printf("乘法:%d * %d = %d\n", a, b, a * b);
    printf("除法:%d / %d = %d\n", a, b, a / b);
    printf("取模:%d %% %d = %d\n", a, b, a % b);
    
    return 0;
}

除法运算注意事项

#include <stdio.h>

int main() {
    // 整数除法
    int a = 5, b = 3;
    printf("整数除法:%d / %d = %d\n", a, b, a / b);  // 1
    
    // 浮点除法
    float x = 5.0f, y = 3.0f;
    printf("浮点除法:%.2f / %.2f = %.2f\n", x, y, x / y);  // 1.67
    
    // 混合除法
    printf("混合除法:%d / %d = %.2f\n", a, b, (float)a / b);  // 1.67
    
    return 0;
}

东巴文提示:整数除法会截断小数部分,如需精确结果需转换为浮点数。

取模运算

#include <stdio.h>

int main() {
    // 取模运算
    printf("10 %% 3 = %d\n", 10 % 3);   // 1
    printf("-10 %% 3 = %d\n", -10 % 3);  // -1
    printf("10 %% -3 = %d\n", 10 % -3);  // 1
    
    // 应用:判断奇偶
    int num = 7;
    if (num % 2 == 0) {
        printf("%d 是偶数\n", num);
    } else {
        printf("%d 是奇数\n", num);
    }
    
    return 0;
}

东巴文说明:取模运算的结果符号与被除数相同。

自增自减运算符

前缀与后缀

东巴文自增自减表

运算符 名称 示例 等价于 东巴文说明
++ 前缀自增 ++a a = a + 1 先加1,再使用
++ 后缀自增 a++ a = a + 1 先使用,再加1
-- 前缀自减 --a a = a - 1 先减1,再使用
-- 后缀自减 a-- a = a - 1 先使用,再减1

示例代码

#include <stdio.h>

int main() {
    int a = 5;
    
    printf("=== 东巴文自增自减示例 ===\n\n");
    
    // 前缀自增
    a = 5;
    printf("前缀自增:\n");
    printf("a = %d\n", a);
    printf("++a = %d\n", ++a);  // 6
    printf("a = %d\n\n", a);    // 6
    
    // 后缀自增
    a = 5;
    printf("后缀自增:\n");
    printf("a = %d\n", a);
    printf("a++ = %d\n", a++);  // 5
    printf("a = %d\n\n", a);    // 6
    
    return 0;
}

复杂表达式

#include <stdio.h>

int main() {
    int a = 5, b;
    
    // 复杂表达式(不推荐)
    b = a++ + ++a;  // 未定义行为
    
    // ✅ 推荐:拆分为多个语句
    a = 5;
    int temp1 = a++;
    int temp2 = ++a;
    b = temp1 + temp2;
    
    printf("b = %d\n", b);
    
    return 0;
}

东巴文警告:避免在同一个表达式中多次修改同一个变量!

关系运算符

比较运算

东巴文关系运算符表

运算符 名称 示例 结果 东巴文说明
== 等于 5 == 5 1 判断相等
!= 不等于 5 != 3 1 判断不等
> 大于 5 > 3 1 大于比较
< 小于 5 < 3 0 小于比较
>= 大于等于 5 >= 5 1 大于等于
<= 小于等于 5 <= 3 0 小于等于

示例代码

#include <stdio.h>

int main() {
    int a = 10, b = 5;
    
    printf("=== 东巴文关系运算示例 ===\n\n");
    printf("a = %d, b = %d\n\n", a, b);
    
    printf("a == b : %d\n", a == b);  // 0
    printf("a != b : %d\n", a != b);  // 1
    printf("a > b  : %d\n", a > b);   // 1
    printf("a < b  : %d\n", a < b);   // 0
    printf("a >= b : %d\n", a >= b);  // 1
    printf("a <= b : %d\n", a <= b);  // 0
    
    return 0;
}

东巴文提示:关系运算的结果是布尔值,在C语言中用整数表示(0为假,非0为真)。

常见错误

#include <stdio.h>

int main() {
    int a = 5;
    
    // ❌ 错误:赋值运算
    if (a = 3) {  // 赋值,不是比较
        printf("a = %d\n", a);  // 会执行
    }
    
    // ✅ 正确:关系运算
    if (a == 3) {
        printf("a 等于 3\n");
    } else {
        printf("a 不等于 3\n");  // 会执行
    }
    
    // ✅ 推荐:常量在左边
    if (3 == a) {  // 如果写成 3 = a 会编译错误
        printf("a 等于 3\n");
    }
    
    return 0;
}

东巴文建议:比较相等时,将常量放在左边,可以避免 === 的混淆。

逻辑运算符

逻辑运算

东巴文逻辑运算符表

运算符 名称 示例 结果 东巴文说明
&& 逻辑与 1 && 1 1 两个都为真才为真
` ` 逻辑或 `1
! 逻辑非 !1 0 真变假,假变真

示例代码

#include <stdio.h>

int main() {
    int a = 1, b = 0;
    
    printf("=== 东巴文逻辑运算示例 ===\n\n");
    printf("a = %d, b = %d\n\n", a, b);
    
    printf("a && b : %d\n", a && b);  // 0
    printf("a || b : %d\n", a || b);  // 1
    printf("!a : %d\n", !a);          // 0
    printf("!b : %d\n", !b);          // 1
    
    return 0;
}

短路求值

#include <stdio.h>

int main() {
    int a = 0, b = 5;
    
    // 短路求值:如果左边为假,右边不执行
    if (a && (b = 10)) {
        printf("条件为真\n");
    }
    printf("b = %d\n", b);  // 5,b没有被修改
    
    // 短路求值:如果左边为真,右边不执行
    if (a || (b = 20)) {
        printf("条件为真\n");
    }
    printf("b = %d\n", b);  // 20,b被修改了
    
    return 0;
}

东巴文说明:逻辑运算符有短路特性,可以提高效率,但也可能导致副作用。

位运算符

位运算

东巴文位运算符表

运算符 名称 示例 结果 东巴文说明
& 按位与 5 & 3 1 两位都为1才为1
` ` 按位或 `5 3`
^ 按位异或 5 ^ 3 6 不同为1,相同为0
~ 按位取反 ~5 -6 0变1,1变0
<< 左移 5 << 1 10 左移n位相当于乘2^n
>> 右移 5 >> 1 2 右移n位相当于除2^n

示例代码

#include <stdio.h>

void printBinary(int num) {
    for (int i = 7; i >= 0; i--) {
        printf("%d", (num >> i) & 1);
    }
}

int main() {
    int a = 5, b = 3;  // 5 = 00000101, 3 = 00000011
    
    printf("=== 东巴文位运算示例 ===\n\n");
    printf("a = %d (二进制: ", a);
    printBinary(a);
    printf(")\n");
    printf("b = %d (二进制: ", b);
    printBinary(b);
    printf(")\n\n");
    
    printf("a & b = %d (二进制: ", a & b);
    printBinary(a & b);
    printf(")\n");
    
    printf("a | b = %d (二进制: ", a | b);
    printBinary(a | b);
    printf(")\n");
    
    printf("a ^ b = %d (二进制: ", a ^ b);
    printBinary(a ^ b);
    printf(")\n");
    
    printf("~a = %d\n", ~a);
    printf("a << 1 = %d\n", a << 1);
    printf("a >> 1 = %d\n", a >> 1);
    
    return 0;
}

位运算应用

#include <stdio.h>

int main() {
    // 判断奇偶
    int num = 7;
    if (num & 1) {
        printf("%d 是奇数\n", num);
    } else {
        printf("%d 是偶数\n", num);
    }
    
    // 交换两个数
    int a = 5, b = 3;
    printf("交换前:a = %d, b = %d\n", a, b);
    a = a ^ b;
    b = a ^ b;
    a = a ^ b;
    printf("交换后:a = %d, b = %d\n", a, b);
    
    // 快速乘除
    int x = 10;
    printf("x * 2 = %d\n", x << 1);  // 20
    printf("x / 2 = %d\n", x >> 1);  // 5
    
    return 0;
}

东巴文提示:位运算效率高,常用于底层编程和性能优化。

赋值运算符

基本赋值

int a = 10;  // 基本赋值

复合赋值

东巴文复合赋值表

运算符 示例 等价于 东巴文说明
+= a += 5 a = a + 5 加赋值
-= a -= 5 a = a - 5 减赋值
*= a *= 5 a = a * 5 乘赋值
/= a /= 5 a = a / 5 除赋值
%= a %= 5 a = a % 5 模赋值
&= a &= 5 a = a & 5 与赋值
` =` `a = 5`
^= a ^= 5 a = a ^ 5 异或赋值
<<= a <<= 1 a = a << 1 左移赋值
>>= a >>= 1 a = a >> 1 右移赋值

示例代码

#include <stdio.h>

int main() {
    int a = 10;
    
    printf("=== 东巴文复合赋值示例 ===\n\n");
    printf("初始值:a = %d\n\n", a);
    
    a += 5;
    printf("a += 5 : a = %d\n", a);  // 15
    
    a -= 3;
    printf("a -= 3 : a = %d\n", a);  // 12
    
    a *= 2;
    printf("a *= 2 : a = %d\n", a);  // 24
    
    a /= 4;
    printf("a /= 4 : a = %d\n", a);  // 6
    
    a %= 4;
    printf("a %%= 4 : a = %d\n", a);  // 2
    
    return 0;
}

条件运算符

三目运算符

东巴文语法

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

东巴文说明

  • 如果条件为真,返回表达式1的值
  • 如果条件为假,返回表达式2的值

示例代码

#include <stdio.h>

int main() {
    int a = 10, b = 5;
    
    // 求最大值
    int max = (a > b) ? a : b;
    printf("最大值:%d\n", max);
    
    // 求绝对值
    int num = -5;
    int abs = (num < 0) ? -num : num;
    printf("绝对值:%d\n", abs);
    
    // 判断奇偶
    int x = 7;
    printf("%d 是%s\n", x, (x % 2 == 0) ? "偶数" : "奇数");
    
    return 0;
}

嵌套使用

#include <stdio.h>

int main() {
    int score = 85;
    
    // 成绩等级判断
    char grade = (score >= 90) ? 'A' :
                 (score >= 80) ? 'B' :
                 (score >= 70) ? 'C' :
                 (score >= 60) ? 'D' : 'F';
    
    printf("成绩:%d, 等级:%c\n", score, grade);
    
    return 0;
}

东巴文建议:三目运算符简洁,但不要过度嵌套,影响可读性。

逗号运算符

基本用法

东巴文语法

表达式1, 表达式2, ..., 表达式n

东巴文说明

  • 从左到右依次执行
  • 整个表达式的值是最后一个表达式的值

示例代码

#include <stdio.h>

int main() {
    int a, b, c;
    
    // 逗号运算符
    c = (a = 5, b = 3, a + b);
    printf("a = %d, b = %d, c = %d\n", a, b, c);  // 5, 3, 8
    
    // for循环中的应用
    for (int i = 0, j = 10; i < j; i++, j--) {
        printf("i = %d, j = %d\n", i, j);
    }
    
    return 0;
}

东巴文提示:逗号运算符常用于for循环中同时操作多个变量。

sizeof运算符

基本用法

sizeof(类型)    // 类型大小
sizeof 变量     // 变量大小

示例代码

#include <stdio.h>

int main() {
    printf("=== 东巴文sizeof示例 ===\n\n");
    
    // 基本类型
    printf("char: %zu 字节\n", sizeof(char));
    printf("int: %zu 字节\n", sizeof(int));
    printf("float: %zu 字节\n", sizeof(float));
    printf("double: %zu 字节\n", sizeof(double));
    
    // 变量
    int a = 10;
    double b = 3.14;
    printf("\n变量a: %zu 字节\n", sizeof a);
    printf("变量b: %zu 字节\n", sizeof b);
    
    // 数组
    int arr[10];
    printf("\n数组arr: %zu 字节\n", sizeof(arr));
    printf("数组元素个数:%zu\n", sizeof(arr) / sizeof(arr[0]));
    
    return 0;
}

运算符优先级

优先级表

东巴文运算符优先级表(从高到低):

优先级 运算符 名称 结合性 东巴文记忆
1 () [] -> . 括号、成员 左到右 最高优先级
2 ! ~ ++ -- sizeof 单目运算符 右到左 一元运算
3 * / % 乘除模 左到右 乘除优先
4 + - 加减 左到右 加减次之
5 << >> 移位 左到右 移位运算
6 < <= > >= 关系 左到右 比较运算
7 == != 相等 左到右 相等判断
8 & 按位与 左到右 位运算
9 ^ 按位异或 左到右 位运算
10 ` ` 按位或 左到右
11 && 逻辑与 左到右 逻辑运算
12 ` ` 逻辑或
13 ?: 条件 右到左 三目运算
14 = += -= 赋值 右到左 赋值运算
15 , 逗号 左到右 最低优先级

示例代码

#include <stdio.h>

int main() {
    int a = 5, b = 3, c = 2;
    
    // 优先级示例
    printf("a + b * c = %d\n", a + b * c);      // 11
    printf("(a + b) * c = %d\n", (a + b) * c);  // 16
    
    printf("a > b && b > c = %d\n", a > b && b > c);  // 1
    
    // 复杂表达式
    int result = a + b * c > 10 && a - b < c;
    printf("result = %d\n", result);
    
    return 0;
}

东巴文建议:不确定优先级时,使用括号明确表达意图。

表达式

什么是表达式?

表达式是由运算符和操作数组成的式子,可以计算出一个值。

东巴文表达式分类

  • 常量表达式:3.14
  • 变量表达式:x
  • 算术表达式:a + b * c
  • 关系表达式:a > b
  • 逻辑表达式:a && b
  • 赋值表达式:a = 10
  • 条件表达式:a > b ? a : b
  • 逗号表达式:(a = 1, b = 2, a + b)

表达式的值

#include <stdio.h>

int main() {
    int a, b;
    
    // 赋值表达式的值
    printf("赋值表达式的值:%d\n", a = 10);  // 10
    
    // 关系表达式的值
    printf("关系表达式的值:%d\n", 5 > 3);   // 1
    
    // 逗号表达式的值
    printf("逗号表达式的值:%d\n", (a = 1, b = 2, a + b));  // 3
    
    return 0;
}

类型转换

隐式类型转换

#include <stdio.h>

int main() {
    int i = 10;
    float f = i;  // int → float
    
    printf("int: %d\n", i);
    printf("float: %f\n", f);
    
    // 混合运算
    int a = 5;
    float b = 2.5f;
    float c = a + b;  // int + float → float
    
    printf("c = %f\n", c);  // 7.5
    
    return 0;
}

显式类型转换

#include <stdio.h>

int main() {
    int a = 5, b = 2;
    
    // 整数除法
    int result1 = a / b;
    printf("整数除法:%d\n", result1);  // 2
    
    // 浮点除法(强制转换)
    float result2 = (float)a / b;
    printf("浮点除法:%f\n", result2);  // 2.500000
    
    return 0;
}

东巴文最佳实践

1. 使用括号明确优先级

// ❌ 不推荐:依赖默认优先级
int result = a + b * c > d && e || f;

// ✅ 推荐:使用括号明确意图
int result = ((a + (b * c)) > d) && e || f;

2. 避免复杂的表达式

// ❌ 不推荐:过于复杂
int result = a++ + ++b * c-- - --d;

// ✅ 推荐:拆分为多个语句
a++;
int temp1 = ++b;
int temp2 = c--;
int temp3 = --d;
int result = a + temp1 * temp2 - temp3;

3. 注意整数溢出

#include <stdio.h>
#include <limits.h>

int main() {
    int a = INT_MAX;
    
    // ❌ 可能溢出
    int b = a + 1;
    
    // ✅ 检查溢出
    if (a > INT_MAX - 1) {
        printf("会溢出!\n");
    }
    
    return 0;
}

4. 合理使用位运算

// ✅ 使用位运算提高效率
int isEven = (num & 1) == 0;  // 判断奇偶
int double = num << 1;         // 乘以2
int half = num >> 1;           // 除以2

东巴文验证清单

完成本章学习后,请确认:

  • 掌握算术运算符的使用
  • 理解自增自减运算符的区别
  • 掌握关系运算符的使用
  • 掌握逻辑运算符的使用
  • 掌握位运算符的使用
  • 掌握赋值运算符的使用
  • 掌握条件运算符的使用
  • 了解逗号运算符的使用
  • 理解运算符优先级
  • 掌握类型转换的方法

下一步学习

掌握运算符与表达式后,你可以继续学习:

如果遇到问题,欢迎访问 东巴文(db-w.cn) 获取帮助!


东巴文(db-w.cn) - 让编程学习更简单

📦 东巴文运算符提示:运算符是程序的工具,掌握运算符的优先级和结合性是编写正确程序的关键。在 db-w.cn,我们会通过大量实例帮你掌握运算符的使用!