第二周

C语言的运算符

运算符分类

C语言中有多种类型的运算符,用于执行各种算术、逻辑和位操作。以下是C语言中常见的运算符类型:

  1. 算术运算符:用于执行基本的算术操作,如加法、减法、乘法、除法、取模等。

    • +:加法运算
    • -:减法运算
    • *:乘法运算
    • /:除法运算
    • %:取模(取余)运算
  2. 关系运算符:用于比较两个值之间的关系,返回一个布尔值(1表示真,0表示假)。

    • ==:等于
    • !=:不等于
    • <:小于
    • >:大于
    • <=:小于等于
    • >=:大于等于
    #include <stdio.h>
    
    int main(void) {
        int num = 65;
        char ch = 'A';
    
        printf("num == ch: %d\n", num == ch);       // 65 == 'B' -> 1 (true)
        printf("num != ch: %d\n", num != ch);       // 65 != 'B' -> 0 (false)
        printf("num > ch: %d\n", num > ch);         // 65 > 'B' -> 0 (false)
        printf("num < ch: %d\n", num < ch);         // 65 < 'B' -> 0 (false)
        printf("num >= ch: %d\n", num >= ch);       // 65 >= 'B' -> 1 (true)
        printf("num <= ch: %d\n", num <= ch);       // 65 <= 'B' -> 1 (true)
    
        return 0;
    }
  3. 逻辑运算符:用于执行逻辑操作,对布尔值进行组合和求反。

    • &&:逻辑与(与)
    • ||:逻辑或(或)
    • !:逻辑非(非)
    #include <stdio.h>
    
    int main(void)
    {
        int a = 1, b = 2, c = 3;
    
        // 逻辑与运算符(&&)
        printf("%d\n", (a < b) && (b < c)); // 1 (true) && 1 (true) -> 1 (true)
        printf("%d\n", (a < b) && (b > c)); // 1 (true) && 0 (false) -> 0 (false)
    
        // 逻辑或运算符(||)
        printf("%d\n", (a < b) || (b < c)); // 1 (true) || 1 (true) -> 1 (true)
        printf("%d\n", (a < b) || (b > c)); // 1 (true) || 0 (false) -> 1 (false)
    
        // 逻辑非运算符(!)
        printf("%d\n", !(a < b)); // !(1 (true)) -> 0 (false)
        printf("%d\n", !(a > b)); // !(0 (false)) -> 1 (true)
    
        return 0;
    }
  4. 位运算符:用于对二进制数据的位进行操作。

    • &:按位与
    • |:按位或
    • ^:按位异或
    • ~:按位取反
    • <<:左移
    • >>:右移
    #include <stdio.h>
    
    int main(void) {
      //unsigned int类型通常32位,以下所有位运算省略高24位的计算,只计算后8位
        unsigned int a = 5;   // 二进制表示为 00000101
        unsigned int b = 3;   // 二进制表示为 00000011
    
        // 按位与运算符(&)
        unsigned int result1 = a & b;    // 00000101 & 00000011 = 00000001
        printf("Result 1: %u\n", result1); // 输出:1
    
        // 按位或运算符(|)
        unsigned int result2 = a | b;    // 00000101 | 00000011 = 00000111
        printf("Result 2: %u\n", result2); // 输出:7
    
        // 按位异或运算符(^)
        unsigned int result3 = a ^ b;    // 00000101 ^ 00000011 = 00000110
        printf("Result 3: %u\n", result3); // 输出:6
    
        // 按位取反运算符(~)
        unsigned int result4 = ~a;       // ~00000101 = 11111010
        printf("Result 4: %u\n", result4); // 输出:4294967290
    
        // 左移运算符(<<)
        unsigned int result5 = a << 2;   // 00000101 << 2 = 00010100
        printf("Result 5: %u\n", result5); // 输出:20
    
        // 右移运算符(>>)
        unsigned int result6 = a >> 1;   // 00000101 >> 1 = 00000010
        printf("Result 6: %u\n", result6); // 输出:2
    
        return 0;
    }
  5. 赋值运算符:用于给变量赋值。

    • =:简单赋值
    • +=:加法赋值
    • -=:减法赋值
    • *=:乘法赋值
    • /=:除法赋值
    • %=:取模赋值
    • <<=:左移赋值
    • >>=:右移赋值
    • &=:按位与赋值
    • |=:按位或赋值
    • ^=:按位异或赋值
    #include <stdio.h>
    
    int main(void)
    {
        int a = 5;
        int b = 3;
        int c = 7;
    
        // 取模赋值运算符(%=)
        b %= a;
        printf("b: %d\n", b); // 输出:3
    
        // 左移赋值运算符(<<=)
        a <<= 2;
        printf("a: %d\n", a); // 输出:20
    
        // 右移赋值运算符(>>=)
        c >>= 1;
        printf("c: %d\n", c); // 输出:3
    
        // 按位与赋值运算符(&=)
        a &= b;
        printf("a: %d\n", a); // 输出:0
    
        // 按位或赋值运算符(|=)
        c |= b;
        printf("c: %d\n", c); // 输出:3
    
        // 按位异或赋值运算符(^=)
        a ^= b;
        printf("a: %d\n", a); // 输出:3
    
        return 0;
    }
  6. 自增和自减运算符:用于对变量进行递增或递减操作。

    • ++:自增
    • --:自减
    #include <stdio.h>
    
    int main(void)
    {
        int a = 5;
        int b = 10;
        int c;
    
        // 自增运算符(++)
        c = a++;           // 先赋值后加1
        printf("%d\n", c); // 输出:5
    
        // 前置自增运算符(++)
        c = ++a;           // 先加1后赋值
        printf("%d\n", c); // 输出:7
    
        // 自减运算符(--)
        c = b--;           // 先赋值后减1
        printf("%d\n", c); // 输出:10
    
        // 前置自减运算符(--)
        c = --b;           // 先减1后赋值
        printf("%d\n", c); // 输出:8
    
        return 0;
    }
  7. 条件运算符:用于根据条件选择不同的值。

    • ? ::条件表达式,也称为三元运算符。

    • 语法格式

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

      如果条件表达式的结果为真(非零),则整个表达式的值为表达式1的值;如果条件表达式的结果为假(零),则整个表达式的值为表达式2的值。

    #include <stdio.h>
    
    int main(void) {
        int a = 5;
        int b = 10;
    
        // 使用条件运算符选择较大的数赋给变量c
        int c = (a > b) ? a : b;
        printf("c: %d\n", c);   // 输出:10
    
        // 使用条件运算符选择绝对值较大的数赋给变量d
        int d = (a > 0) ? a : -a;
        printf("d: %d\n", d);   // 输出:5
    
        return 0;
    }
  8. 逗号运算符

    逗号运算符是C语言中的一个运算符,它用逗号 , 分隔多个表达式,形成一个逗号表达式。逗号表达式的求值规则是从左到右依次对每个表达式进行求值,并返回最右边表达式的值作为整个逗号表达式的结果。

    1. 表达式顺序执行:逗号运算符可以用于在同一个语句中按顺序执行多个表达式,每个表达式都会被求值,但只有最后一个表达式的值会作为整个逗号表达式的结果。例如:

      int a = 1, b = 2, c = 3;
      int result = (a++, b++, c++, a + b + c);  // 逐个增加 a、b、c 的值,然后计算 a + b + c 的结果,赋给 result
    2. 多个初始化语句:逗号运算符可以在变量初始化时一次性初始化多个变量。例如:

      int x = 1, y = 2, z = 3;
      int x, y, z;
  9. 其他运算符:还有一些其他类型的运算符,如指针运算符、sizeof运算符、类型转换运算符等。

运算符优先级

1.第一周-2023-06-09-11-36-00

1.第一周-2023-06-09-11-36-08

1.第一周-2023-06-09-11-36-21

运算符优先级示例代码

#include <stdio.h>

int main(void) {
    int a = 5, b = 3, c = 7;
    int result1 = a + b * c;        // 5 + 3 * 7 = 26
    int result2 = (a + b) * c;      // (5 + 3) * 7 = 56
    int result3 = a * b / c;        // 5 * 3 / 7 = 2
    int result4 = a * (b / c);      // 5 * (3 / 7) = 0
    int result5 = a % b + c;        // 5 % 3 + 7 = 9
    int result6 = a << b + c;       // 5 << (3 + 7) = 5120
    int result7 = (a << b) + c;     // (5 << 3) + 7 = 47
    int result8 = a < b && b < c;   // 5 < 3 && 3 < 7 = 0 (false)
    int result9 = a < b || b < c;   // 5 < 3 || 3 < 7 = 1 (true)
    int result10 = a == b ? c : a;  // 5 == 3 ? 7 : 5 = 5

    printf("Result 1: %d\n", result1);
    printf("Result 2: %d\n", result2);
    printf("Result 3: %d\n", result3);
    printf("Result 4: %d\n", result4);
    printf("Result 5: %d\n", result5);
    printf("Result 6: %d\n", result6);
    printf("Result 7: %d\n", result7);
    printf("Result 8: %d\n", result8);
    printf("Result 9: %d\n", result9);
    printf("Result 10: %d\n", result10);

    return 0;
}

类型转换

类型转换(Type Conversion)是将一个数据类型的值转换为另一个数据类型的过程。在C语言中,类型转换可分为隐式类型转换(Implicit Conversion)和显式类型转换(Explicit Conversion)两种形式。

  1. 隐式类型转换:隐式类型转换是指在表达式中自动进行的类型转换,不需要显式地指定转换操作符。常见的隐式类型转换有:

    • 涉及两种类型的运算,两个值会被分别转换成两种类型的更高级别。

      类型的级别从高至低依次是long double、double、float、unsigned long long、long long、unsigned long、long、unsigned int、int。例外的情况是,当long 和 int 的大小相同时,unsigned int比long的级别高。之所以short和char类型没有列出,是因为它们已经被升级到int或unsigned int。

    • 在赋值表达式语句中,计算的最终结果会被转换成被赋值变量的类型。这个过程可能导致类型升级或降级(demotion)。所谓降级,是指把一种类型转换成更低级别的类型。

    #include <stdio.h>
    
    int main(void)
    {
        int a = 5;
        double b = 3.14;
    
        // 隐式类型转换
        double c = a; // 将整型变量a隐式转换为double类型
        int d = b;    // 将double类型变量b隐式转换为整型
    
        printf("c: %f\n", c); // 输出:5.000000
        printf("d: %d\n", d); // 输出:3
        printf("%f", a + b);  // 输出:8.140000
    }
  2. 显式类型转换:显式类型转换是通过显式地使用类型转换操作符来执行的。它允许我们将一个数据类型强制转换为另一个数据类型。显式类型转换的语法形式如下:

    (目标类型) 表达式
    #include <stdio.h>
    
    int main(void) {
        int a = 5;
        double b = 3.14;
    
        // 显式类型转换
        int e = (int)b;        // 将double类型变量b显式转换为整型
        printf("e: %d\n", e);  // 输出:3
    
        return 0;
    }

表达式语句,空语句,复合语句

在C语言中,有三种常见的语句类型:表达式语句(Expression Statement),空语句(Empty Statement)和复合语句(Compound Statement)。

  1. 表达式语句(Expression Statement):表达式语句由一个表达式和一个分号组成,用于执行一个表达式并丢弃其结果。表达式可以是函数调用、赋值表达式、递增递减表达式等。例如:

    x = 5;           // 赋值表达式作为表达式语句
    printf("Hello"); // 函数调用作为表达式语句
    x++;
  2. 空语句(Empty Statement):空语句只包含一个分号,用于表示一个空操作。空语句在某些情况下可以用作占位符,或者在循环中作为一个空的循环体。例如:

    ; // 空语句
    for (int i = 0; i < 10; i++) 
        printf(); // 空循环体

    空语句不做任何操作,它在语法上是合法的语句,但不会有任何实际的影响。

  3. 复合语句(Compound Statement):复合语句是由一对花括号 {} 包围的语句块,可以包含多条语句。复合语句常用于定义函数体或在控制流语句中使用。例如:

    {
        int x = 5;          // 定义变量
        printf("Value: %d", x);
        x++;                // 修改变量的值
        printf("Updated Value: %d", x);
    }

    这些语句类型在C语言中用于不同的场景和目的。表达式语句用于执行表达式并丢弃结果,空语句表示一个空操作,复合语句用于组织多个语句形成一个语句块。了解这些语句类型可以帮助我们编写清晰、有效的代码。