ThatManK Mobile Article

运算符与表达式

Category: C语言 Tutorial: 教程一 Published: 2026-04-07 13:58 Views: 20 Likes: 0 Comments: 0
5. 运算符与表达式

运算符是 C 语言中用于执行各种操作的符号或关键字。运算符与操作数结合形成表达式,表达式可以计算出一个值。理解各种运算符及其优先级与结合性,是编写正确和高效 C 程序的基础。

5.1 算术运算符

算术运算符用于执行基本的数学计算,包括加、减、乘、除和取模(余数)等操作。

常见算术运算符

| 运算符 | 描述 | 示例 | 解释 |
| :---: | :---: | :---: | :---: |
| + | 加法 | a + b | 将两个操作数相加 |
| - | 减法 | a - b | 从第一个操作数中减去第二个操作数 |
| * | 乘法 | a * b | 将两个操作数相乘 |
| / | 除法 | a / b | 将第一个操作数除以第二个操作数 |
| % | 取模(余数) | a % b | 计算第一个操作数除以第二个操作数的余数 |

示例与详细解释
#include <stdio.h>

int main() {
    int a = 15;
    int b = 4;
    int sum, difference, product, quotient, remainder;

    // 加法
    sum = a + b; // 15 + 4 = 19
    printf("a + b = %d\n", sum);

    // 减法
    difference = a - b; // 15 - 4 = 11
    printf("a - b = %d\n", difference);

    // 乘法
    product = a * b; // 15 * 4 = 60
    printf("a * b = %d\n", product);

    // 除法
    quotient = a / b; // 15 / 4 = 3 (整数除法,舍去小数部分)
    printf("a / b = %d\n", quotient);

    // 取模
    remainder = a % b; // 15 % 4 = 3
    printf("a %% b = %d\n", remainder);

    return 0;
}

输出

a + b = 19
a - b = 11
a * b = 60
a / b = 3
a % b = 3
注意事项
  1. 整数除法:当两个整数相除时,结果也是一个整数,任何小数部分都会被舍去。
  2. 取模运算:取模运算仅适用于整数类型,计算两个整数相除后的余数。
更多示例
#include <stdio.h>

int main() {
    float x = 5.5;
    float y = 2.2;
    float result;

    // 加法
    result = x + y; // 5.5 + 2.2 = 7.7
    printf("x + y = %.1f\n", result);

    // 减法
    result = x - y; // 5.5 - 2.2 = 3.3
    printf("x - y = %.1f\n", result);

    // 乘法
    result = x * y; // 5.5 * 2.2 = 12.1
    printf("x * y = %.1f\n", result);

    // 除法
    result = x / y; // 5.5 / 2.2 = 2.5
    printf("x / y = %.1f\n", result);

    return 0;
}

输出

x + y = 7.7
x - y = 3.3
x * y = 12.1
x / y = 2.5
5.2 关系运算符

关系运算符用于比较两个值,结果是一个布尔值(真或假)。这些运算符常用于条件判断和循环控制。

常见关系运算符

| 运算符 | 描述 | 示例 | 解释 |
| ------ | -------- | -------- | -------------------------------- |
| == | 等于 | a == b | 如果 a 等于 b,结果为真(1) |
| != | 不等于 | a != b | 如果 a 不等于 b,结果为真(1) |
| > | 大于 | a > b | 如果 a 大于 b,结果为真(1) |
| < | 小于 | a < b | 如果 a 小于 b,结果为真(1) |
| >= | 大于等于 | a >= b | 如果 a 大于等于 b,结果为真(1) |
| <= | 小于等于 | a <= b | 如果 a 小于等于 b,结果为真(1) |

示例与详细解释
#include <stdio.h>

int main() {
    int a = 10;
    int b = 20;

    // 等于
    if (a == b) {
        printf("a 等于 b\n");
    } else {
        printf("a 不等于 b\n");
    }

    // 不等于
    if (a != b) {
        printf("a 不等于 b\n");
    }

    // 大于
    if (a > b) {
        printf("a 大于 b\n");
    } else {
        printf("a 不大于 b\n");
    }

    // 小于
    if (a < b) {
        printf("a 小于 b\n");
    }

    // 大于等于
    if (a >= 10) {
        printf("a 大于等于 10\n");
    }

    // 小于等于
    if (b <= 20) {
        printf("b 小于等于 20\n");
    }

    return 0;
}

输出

a 不等于 b
a 不大于 b
a 小于 b
a 大于等于 10
b 小于等于 20
更多示例
#include <stdio.h>

int main() {
    int x = 5;
    int y = 5;
    int z = 10;

    // 使用关系运算符进行比较
    printf("x == y: %d\n", x == y); // 1(真)
    printf("x != z: %d\n", x != z); // 1(真)
    printf("z > y: %d\n", z > y);   // 1(真)
    printf("x < z: %d\n", x < z);   // 1(真)
    printf("y >= x: %d\n", y >= x); // 1(真)
    printf("z <= 10: %d\n", z <= 10); // 1(真)

    return 0;
}

输出

x == y: 1
x != z: 1
z > y: 1
x < z: 1
y >= x: 1
z <= 10: 1
注意事项
  • 布尔值:C 语言中,真用1表示,假用0表示。
  • 类型兼容性:在比较时,操作数应尽量类型一致,避免隐式类型转换带来的问题。
5.3 逻辑运算符

逻辑运算符用于连接两个或多个条件表达式,产生一个布尔值结果。这些运算符在条件判断和控制结构中尤为重要。

常见逻辑运算符

| 运算符 | 描述 | 示例 | 解释 |
| ------ | ------------- | -------- | ------------------------------------------------------ |
| && | 逻辑与(AND) | a && b | 如果 a 和 b 都为真,结果为真(1) |
| | | | 逻辑或(OR) |
| ! | 逻辑非(NOT) | !a | 如果 a 为假,结果为真(1);如果 a 为真,结果为假(0) |

示例与详细解释
#include <stdio.h>

int main() {
    int a = 10;
    int b = 20;
    int c = 30;

    // 逻辑与运算
    if (a < b && b < c) {
        printf("a < b 且 b < c\n");
    }

    // 逻辑或运算
    if (a > b || b < c) {
        printf("a > b 或 b < c\n");
    }

    // 逻辑非运算
    if (!(a > b)) {
        printf("!(a > b) 即 a <= b\n");
    }

    return 0;
}

输出

a < b 且 b < c
a > b 或 b < c
!(a > b) 即 a <= b
更多示例
#include <stdio.h>

int main() {
    int x = 5;
    int y = 10;

    // 逻辑与
    if (x > 0 && y > 0) {
        printf("x 和 y 都是正数\n");
    }

    // 逻辑或
    if (x < 0 || y > 0) {
        printf("x 是负数 或 y 是正数\n");
    }

    // 逻辑非
    if (!(x == y)) {
        printf("x 不等于 y\n");
    }

    return 0;
}

输出

x 和 y 都是正数
x 是负数 或 y 是正数
x 不等于 y
注意事项
  • 短路评估:逻辑与和逻辑或运算符具有短路特性。例如,a && b,如果 a 为假,b 将不再被计算。
  • 优先级:逻辑运算符的优先级低于关系运算符,高于赋值运算符。使用括号可以明确运算顺序。
5.4 位运算符

位运算符用于对整数类型的位(0 和 1)进行操作。这些运算符在底层编程、硬件控制和高效算法实现中非常有用。

常见位运算符

| 运算符 | 描述 | 示例 | 解释 |
| :---: | :---: | :---: | :---: |
| & | 按位与 | a & b | 对应位都为 1 时结果为 1,否则为 0 |
| | | 按位或 | a | b |
| ^ | 按位异或 | a ^ b | 对应位不同则为 1,相同则为 0 |
| ~ | 按位取反 | ~a | 对每一位取反,即 0 变 1,1 变 0 |
| << | 左移 | a << 2 | 将位向左移动指定的位数 |
| >> | 右移 | a >> 2 | 将位向右移动指定的位数 |

示例与详细解释
#include <stdio.h>

int main() {
    unsigned char a = 5;    // 二进制:00000101
    unsigned char b = 9;    // 二进制:00001001
    unsigned char result;

    // 按位与
    result = a & b; // 00000101 & 00001001 = 00000001
    printf("a & b = %d\n", result); // 输出 1

    // 按位或
    result = a | b; // 00000101 | 00001001 = 00001101
    printf("a | b = %d\n", result); // 输出 13

    // 按位异或
    result = a ^ b; // 00000101 ^ 00001001 = 00001100
    printf("a ^ b = %d\n", result); // 输出 12

    // 按位取反
    result = ~a; // ~00000101 = 11111010
    printf("~a = %d\n", result); // 输出 250(对于unsigned char)

    // 左移
    result = a << 2; // 00000101 << 2 = 00010100
    printf("a << 2 = %d\n", result); // 输出 20

    // 右移
    result = b >> 2; // 00001001 >> 2 = 00000010
    printf("b >> 2 = %d\n", result); // 输出 2

    return 0;
}

输出

a & b = 1
a | b = 13
a ^ b = 12
~a = 250
a << 2 = 20
b >> 2 = 2
更多示例
#include <stdio.h>

int main() {
    unsigned int x = 12; // 二进制:00001100
    unsigned int y = 5;  // 二进制:00000101
    unsigned int z;

    // 按位与
    z = x & y; // 00001100 & 00000101 = 00000100 (4)
    printf("x & y = %u\n", z);

    // 按位或
    z = x | y; // 00001100 | 00000101 = 00001101 (13)
    printf("x | y = %u\n", z);

    // 按位异或
    z = x ^ y; // 00001100 ^ 00000101 = 00001001 (9)
    printf("x ^ y = %u\n", z);

    // 按位取反
    z = ~x; // ~00001100 = 11110011... (对于unsigned int, 结果依系统而定)
    printf("~x = %u\n", z);

    // 左移
    z = x << 1; // 00001100 << 1 = 00011000 (24)
    printf("x << 1 = %u\n", z);

    // 右移
    z = y >> 1; // 00000101 >> 1 = 00000010 (2)
    printf("y >> 1 = %u\n", z);

    return 0;
}

输出

x & y = 4
x | y = 13
x ^ y = 9
~x = 4294967283
x << 1 = 24
y >> 1 = 2
应用场景
  1. 位掩码:使用按位与操作提取特定位的数据。
   #include <stdio.h>

   int main() {
       unsigned char flags = 0b10101100; // 假设这是一个标志位
       unsigned char mask = 0b00001000;  // 掩码,提取第四位

       unsigned char result = flags & mask;
       if (result) {
           printf("第四位是1\n");
       } else {
           printf("第四位是0\n");
       }

       return 0;
   }

输出

   第四位是1
  1. 设置、清除和切换位
   #include <stdio.h>

   int main() {
       unsigned char flags = 0b00000000; // 初始状态

       // 设置第三位
       flags |= 0b00000100; // 00000000 | 00000100 = 00000100
       printf("设置第三位后: %u\n", flags); // 输出 4

       // 清除第三位
       flags &= ~0b00000100; // 00000100 & 11111011 = 00000000
       printf("清除第三位后: %u\n", flags); // 输出 0

       // 切换第二位
       flags ^= 0b00000010; // 00000000 ^ 00000010 = 00000010
       printf("切换第二位后: %u\n", flags); // 输出 2

       // 再次切换第二位
       flags ^= 0b00000010; // 00000010 ^ 00000010 = 00000000
       printf("再次切换第二位后: %u\n", flags); // 输出 0

       return 0;
   }

输出

   设置第三位后: 4
   清除第三位后: 0
   切换第二位后: 2
   再次切换第二位后: 0
注意事项
  • 优先级:位运算符的优先级低于算术运算符,高于赋值运算符。使用括号可以明确运算顺序。
  • 类型:位运算符仅适用于整数类型(intcharlong等)。
5.5 赋值运算符

赋值运算符用于将右侧的值赋给左侧的变量。C 语言提供了多种赋值运算符,以简化变量的赋值操作。

常见赋值运算符

| 运算符 | 描述 | 示例 | 解释 |
| ------ | -------------- | ------------ | ------------------- |
| = | 简单赋值 | a = b | 将 b 的值赋给 a |
| += | 加后赋值 | 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 |
| <<= | 左移后赋值 | a <<= 2 | 等价于 a = a << 2 |
| >>= | 右移后赋值 | a >>= 2 | 等价于 a = a >> 2 |
| &= | 按位与后赋值 | a &= b | 等价于 a = a & b |
| | = | 按位或后赋值 | a | | ^= | 按位异或后赋值 | a ^= b | 等价于 a = a ^ b | ##### 示例与详细解释 @@H20@@ **输出**: @@H21@@ ##### 注意事项 - **操作顺序**:赋值运算符具有从右到左的结合性。 - **优先级**:赋值运算符的优先级较低,通常与括号结合使用以确保正确的运算顺序。 ##### 5.6 条件运算符 **条件运算符**(又称三元运算符)是一种简洁的条件判断方法,语法形式为条件 ? 表达式1 : 表达式2。根据条件的真假,选择执行表达式 1 或表达式 2。 ##### 条件运算符的语法 @@H22@@ - **条件**:一个布尔表达式,如果为真(非零),则执行表达式 1;否则执行表达式 2。 - **表达式 1** 和 **表达式 2**:可以是任何类型的表达式。 ##### 示例与详细解释 @@H23@@ **输出**: @@H24@@ ##### 更多示例 @@H25@@ **输出**: @@H26@@ ##### 注意事项 - **可读性**:虽然条件运算符可以简化代码,但过度使用或嵌套使用可能会降低代码的可读性。应在保持简洁的同时,确保代码清晰易懂。 - **类型一致性**:条件运算符的两个表达式(表达式 1 和表达式 2)应尽量类型一致,以避免不必要的类型转换。 ##### 5.7 运算符优先级与结合性 在 C 语言中,**运算符优先级**决定了表达式中不同运算符的计算顺序,而**结合性**决定了当具有相同优先级的运算符出现在表达式中时,运算的方向。 ##### 运算符优先级 不同运算符具有不同的优先级。优先级高的运算符会先被计算。以下是常见运算符的优先级列表(从高到低)。 | 优先级 | 运算符 | 描述 | | ------ | ---------------------------------------------------- | ---------------------------- | | 1 | () [] -> . | 函数调用、数组下标、成员访问 | | 2 | ! ~ ++ -- - + & | 单目运算符 | | 3 | / % | 乘法、除法、取模 | | 4 | + - | 加法、减法 | | 5 | << >> | 左移、右移 | | 6 | < <= > >= | 关系运算符 | | 7 | == != | 相等运算符 | | 8 | & | 按位与 | | 9 | ^ | 按位异或 | | 10 | | | | 11 | && | 逻辑与 | | 12 | | |
| 13 | ?: | 条件运算符(三元运算符) |
| 14 | = += -= *= /= %= <<= >>= &= ^= | = |
| 15 | , | 逗号运算符 |

运算符结合性

结合性决定了当表达式中存在多个相同优先级的运算符时,运算的顺序。

| 结合性 | 运算符 |
| -------- | -------------------------------------------------------- |
| 从左到右 | () [] -> .、算术运算符、关系运算符、逻辑运算符等 |
| 从右到左 | 赋值运算符、条件运算符(三元运算符)等 |

示例与详细解释
示例 1:优先级高的运算符先计算
#include <stdio.h>

int main() {
    int a = 5;
    int b = 10;
    int c;

    // 运算符优先级示例
    c = a + b * 2; // 先计算 b * 2,再加 a
    printf("a + b * 2 = %d\n", c); // 输出 25

    c = (a + b) * 2; // 使用括号改变优先级,先计算 a + b,再乘以2
    printf("(a + b) * 2 = %d\n", c); // 输出 30

    return 0;
}

输出

a + b * 2 = 25
(a + b) * 2 = 30
示例 2:结合性示例
#include <stdio.h>

int main() {
    int x = 1;
    int y = 2;
    int z = 3;
    int a, b;

    // 从左到右结合性
    a = x = y + z; // y + z = 5, x = 5, a = 5
    printf("a = %d, x = %d\n", a, x); // 输出 a = 5, x = 5

    // 赋值运算符的右到左结合性
    b = a = x = 10; // x = 10, a = 10, b = 10
    printf("a = %d, b = %d, x = %d\n", a, b, x); // 输出 a = 10, b = 10, x = 10

    return 0;
}

输出

a = 5, x = 5
a = 10, b = 10, x = 10
示例 3:条件运算符的优先级与结合性
#include <stdio.h>

int main() {
    int a = 5, b = 10, c = 15;
    int result;

    // 条件运算符的优先级较低,需要使用括号确保运算顺序
    result = a > b ? a : b > c ? b : c;
    // 等价于: result = (a > b) ? a : (b > c ? b : c)
    printf("Result: %d\n", result); // 输出 15

    return 0;
}

输出

Result: 15
运算符优先级表

以下是 C 语言中常见运算符的优先级和结合性列表,便于查阅和参考。

| 优先级 | 运算符 | 描述 | 结合性 |
| ------ | ---------------------------------------------------- | ---------------------------- | ---------- |
| 1 | () [] -> . | 函数调用、数组下标、成员访问 | 从左到右 |
| 2 | ! ~ ++ -- - + * & | 单目运算符 | 从右到左 |
| 3 | * / % | 乘法、除法、取模 | 从左到右 |
| 4 | + - | 加法、减法 | 从左到右 |
| 5 | << >> | 左移、右移 | 从左到右 |
| 6 | < <= > >= | 关系运算符 | 从左到右 |
| 7 | == != | 相等运算符 | 从左到右 |
| 8 | & | 按位与 | 从左到右 |
| 9 | ^ | 按位异或 | 从左到右 |
| 10 | | | 按位或 |
| 11 | && | 逻辑与 | 从左到右 |
| 12 | | | |
| 13 | ?: | 条件运算符(三元运算符) | 从右到左 |
| 14 | = += -= *= /= %= <<= >>= &= ^= | = | 赋值运算符 |
| 15 | , | 逗号运算符 | 从左到右 |

5.8 总结

运算符与表达式是 C 语言编程中的核心概念。通过理解不同运算符的功能、优先级和结合性,能够编写出逻辑正确且高效的代码。以下是本节的关键点:

  1. 算术运算符:用于基本的数学计算,如加、减、乘、除和取模。
  2. 关系运算符:用于比较两个值,返回布尔值(真或假)。
  3. 逻辑运算符:用于连接多个条件表达式,产生布尔值结果。
  4. 位运算符:用于对整数类型的位进行操作,适用于底层编程和高效算法。
  5. 赋值运算符:用于将值赋给变量,提供多种简化赋值的方式。
  6. 条件运算符:一种简洁的条件判断方法,通常用于简化if-else语句。
  7. 运算符优先级与结合性:决定表达式中运算的顺序和方向,确保代码按预期执行。