C语言中的运算符

一,算数运算符

基本算术运算符:

加法(+):用于两个数相加。例如 int a = 3 + 5;,结果 a 的值为 8。

减法(-):两个数相减。如 int b = 7 - 4;,b 的值为 3。

乘法(*):两数相乘。int c = 2 * 6;,c 为 12。

除法(/):整数除法会截断结果的小数部分。例如 int d = 10 / 3;,d 的值为 3。

取余(%):也叫模运算,用于计算两个整数相除的余数。例如 int e = 10 % 3;,e 的值为 1。

运行结果:

自增和自减运算符:

自增(++):使变量的值增加 1。分为前置和后置两种形式。前置自增(如 ++a)先将变量的值加 1,然后再使用变量的值;后置自增(如 a++)先使用变量的值,然后再将变量的值加 1。自减(--):使变量的值减少 1,也有前置和后置两种形式。

运行结果:

二,关系运算符

一、等于运算符(==)

  1. 作用:判断两个值是否相等。

    • 例如:if (a == b),如果变量 a 的值等于变量 b 的值,那么这个条件判断为真。
    • 不仅可以用于基本数据类型(如整数、浮点数、字符等)的比较,也可以用于指针的比较(判断两个指针是否指向同一个地址)。
  2. 注意事项:

    • 与赋值运算符(=)容易混淆。赋值运算符是将一个值赋给一个变量,而等于运算符是判断两个值是否相等。例如,if (a = 5)是错误的用法,应该是if (a == 5)

二、不等于运算符(!=)

  1. 作用:判断两个值是否不相等。

    • 例如:if (a!= b),如果变量 a 的值不等于变量 b 的值,那么这个条件判断为真。
    • 同样可以用于各种数据类型和指针的比较。
  2. 注意事项:与等于运算符相对应,在使用时要注意逻辑的正确性。

三、大于运算符(>)

  1. 作用:判断左边的值是否大于右边的值。

    • 例如:if (a > b),如果变量 a 的值大于变量 b 的值,那么这个条件判断为真。
    • 适用于数值类型的比较,对于字符类型,实际上是比较其对应的 ASCII 码值。
  2. 注意事项:只能用于可比较大小的数据类型,对于没有大小关系的数据类型(如结构体,除非自定义了比较函数)不能使用。

四、小于运算符(<)

  1. 作用:判断左边的值是否小于右边的值。

    • 例如:if (a < b),如果变量 a 的值小于变量 b 的值,那么这个条件判断为真。
    • 与大于运算符类似,适用于数值类型和字符类型的比较。
  2. 注意事项:同样要注意数据类型的适用性。

五、大于等于运算符(>=)

  1. 作用:判断左边的值是否大于或等于右边的值。

    • 例如:if (a >= b),如果变量 a 的值大于或等于变量 b 的值,那么这个条件判断为真。
    • 在需要判断一个值是否在某个范围之上(包括边界值)时非常有用。
  2. 注意事项:确保比较的逻辑符合预期。

六、小于等于运算符(<=)

  1. 作用:判断左边的值是否小于或等于右边的值。

    • 例如:if (a <= b),如果变量 a 的值小于或等于变量 b 的值,那么这个条件判断为真。
    • 常用于判断一个值是否在某个范围之下(包括边界值)。
  2. 注意事项:与其他关系运算符一样,注意数据类型和逻辑的正确性。

关系运算符通常在条件判断语句(如 if 语句、while 循环等)中使用,以控制程序的流程根据不同的比较结果执行不同的代码分支。

运行结果:

三,逻辑运算符

一、逻辑与运算符(&&)

  1. 作用:

    • 当且仅当两个条件都为真时,整个表达式的结果才为真。如果其中任何一个条件为假,那么整个表达式的结果为假。
    • 例如:if (a > 0 && b < 10),只有当变量 a 的值大于 0 并且变量 b 的值小于 10 时,这个条件判断才为真。
  2. 短路特性:

    • 如果第一个条件为假,那么就不会再去判断第二个条件,因为无论第二个条件的结果如何,整个表达式的结果都已经确定为假。
    • 例如:if ((a == NULL) && (a->value == 5)),如果 a 是一个指针且为 NULL,那么就不会去判断 a->value == 5 这个条件,因为此时整个表达式已经确定为假,避免了因访问 NULL 指针而导致的错误。

二、逻辑或运算符(||)

  1. 作用:

    • 只要两个条件中有一个为真,整个表达式的结果就为真。只有当两个条件都为假时,整个表达式的结果才为假。
    • 例如:if (a == 5 || b == 8),如果变量 a 的值等于 5 或者变量 b 的值等于 8,那么这个条件判断就为真。
  2. 短路特性:

    • 如果第一个条件为真,那么就不会再去判断第二个条件,因为无论第二个条件的结果如何,整个表达式的结果都已经确定为真。
    • 例如:if ((a!= NULL) || (b = allocateMemory())),如果 a 不是 NULL,那么就不会去调用 allocateMemory() 函数来判断第二个条件,因为此时整个表达式已经确定为真,避免了不必要的函数调用。

三、逻辑非运算符(!)

  1. 作用:

    • 对一个条件取反。如果条件为真,那么 ! 操作后结果为假;如果条件为假,那么 ! 操作后结果为真。
    • 例如:if (!(a > b)),如果变量 a 的值不大于变量 b 的值,那么这个条件判断为真。
  2. 注意事项:

    • 逻辑非运算符是一元运算符,只作用于一个条件表达式。
    • 在使用时要注意逻辑的正确性,避免因取反而导致的意外结果。

逻辑运算符在 C 语言中广泛用于条件判断和控制程序的流程,通过组合多个条件可以实现复杂的逻辑判断。

运行结果:

四,位运算符

在 C 语言中,位运算符用于对二进制位进行操作。所以进行比较的时候是把我们常见的十进制数字转换为二进制数字,和其他语言不太一样,例如java语言的位运算符,有的也只是逻辑运算符的功能.

一、按位与运算符(&)

  1. 作用:

    • 对应位都为 1 时结果为 1,否则为 0。
    • 例如,假设 a = 5(二进制为 0101),b = 3(二进制为 0011),那么 a & b 的结果为 1(二进制为 0001)。
  2. 应用场景:

    • 可以用于提取某些特定的位。比如要判断一个整数的最低位是否为 0,可以将这个整数与 1(二进制为 0001)进行按位与操作,如果结果为 0,则最低位为 0。
    • 用于清除某些特定的位。将一个数与一个所有要清除的位为 0 的数进行按位与操作,就可以将这些位清为 0。

二、按位或运算符(|)

  1. 作用:

    • 对应位只要有一个为 1 时结果为 1。
    • 例如,对于上面的 a = 5b = 3a | b 的结果为 7(二进制为 0111)。
  2. 应用场景:

    • 设置某些特定的位。将一个数与一个所有要设置的位为 1 的数进行按位或操作,就可以将这些位设置为 1。
    • 合并两个标志或状态。如果不同的位代表不同的状态,可以使用按位或操作来合并两个状态。

三、按位异或运算符(^)

  1. 作用:

    • 对应位不同时结果为 1。
    • 例如,a = 5b = 3a ^ b 的结果为 6(二进制为 0110)。
  2. 应用场景:

    • 交换两个变量的值而不使用临时变量。例如,a = a ^ b; b = a ^ b; a = a ^ b;,通过三次异或操作可以实现 ab 的值交换。
    • 加密和解密。在一些简单的加密算法中,可以使用异或操作对数据进行加密,然后再用相同的密钥进行异或操作来解密。

四、左移运算符(<<)

  1. 作用:

    • 将一个数的二进制位向左移动指定的位数。左边移出的位被丢弃,右边补 0。
    • 例如,a = 5a << 2 的结果为 20(二进制为 10100)。
  2. 应用场景:

    • 快速实现乘以 2 的幂次方的操作。将一个数左移 n 位,相当于乘以 2 的 n 次方。
    • 在某些位操作场景中,用于调整位的位置。

五、右移运算符(>>)

  1. 作用:

    • 将一个数的二进制位向右移动指定的位数。如果是无符号数,左边补 0;如果是有符号数,根据符号位进行填充(正数补 0,负数补 1)。
    • 例如,a = -5(二进制为 11111111111111111111111111111011),a >> 2 的结果为 -2(二进制为 11111111111111111111111111111110)。
  2. 应用场景:

    • 快速实现除以 2 的幂次方的操作。将一个数右移 n 位,相当于除以 2 的 n 次方。
    • 在某些需要对二进制位进行调整的场景中使用。

运算结果:

运算结果:

五,赋值运算符

一、基本赋值运算符(=)

  1. 作用:

    • 将右侧的值赋给左侧的变量。
    • 例如,int a = 5;,这里将整数 5 赋值给变量 a
  2. 注意事项:

    • 左侧必须是一个可修改的左值,通常是变量名、数组元素或指针所指向的内存位置等。
    • 赋值运算符的优先级相对较低,在复杂表达式中要注意使用括号来明确运算顺序。

二、复合赋值运算符

  1. 加法赋值运算符(+=):

    • 作用:先将左侧变量的值与右侧的值相加,然后将结果再赋给左侧变量。
    • 例如,int b = 3; b += 2;,相当于 b = b + 2;,执行后 b 的值为 5。
  2. 减法赋值运算符(-=):

    • 作用:先将左侧变量的值减去右侧的值,然后将结果再赋给左侧变量。
    • 例如,int c = 5; c -= 3;,相当于 c = c - 3;,执行后 c 的值为 2。
  3. 乘法赋值运算符(*=):

    • 作用:先将左侧变量的值与右侧的值相乘,然后将结果再赋给左侧变量。
    • 例如,int d = 4; d *= 3;,相当于 d = d * 3;,执行后 d 的值为 12。
  4. 除法赋值运算符(/=):

    • 作用:先将左侧变量的值除以右侧的值,然后将结果再赋给左侧变量。
    • 例如,int e = 10; e /= 2;,相当于 e = e / 2;,执行后 e 的值为 5。注意,如果右侧的值为 0,会导致运行时错误。
  5. 取余赋值运算符(%=):

    • 作用:先将左侧变量的值与右侧的值进行取余运算,然后将结果再赋给左侧变量。
    • 例如,int f = 11; f %= 4;,相当于 f = f % 4;,执行后 f 的值为 3。

复合赋值运算符的优点在于可以使代码更加简洁,并且在某些情况下可以提高程序的执行效率,因为编译器可能会对复合赋值运算符进行一些优化。

六,逗号运算符和三目运算符

1,逗号运算符

(1)、逗号运算符的作用
  1. 连接多个表达式:

    • 逗号运算符可以将多个表达式依次连接起来,从左到右依次计算每个表达式的值。
    • 例如:int a = 1, b = 2, c = 3;,这里使用逗号运算符同时声明并初始化了三个变量。
  2. 确定整个逗号表达式的值:

    • 逗号表达式的值是最后一个表达式的值。
    • 例如:int x; x = (a = 5, b = a + 2, c = b * 3);,这里先给 a 赋值为 5,然后 b 被赋值为 a + 2 即 7,接着 c 被赋值为 b * 3 即 21,最后整个逗号表达式的值为 21,所以 x 的值为 21。
(2)、逗号运算符的应用场景
  1. 在 for 循环中:

    • 逗号运算符在 for 循环的初始化和更新部分经常被使用,可以同时初始化多个变量或进行多个变量的更新操作。
    • 例如:for (int i = 0, j = 10; i < j; i++, j--) { /* loop body */ },这里在 for 循环的初始化部分同时初始化了两个变量 ij,在更新部分同时对 i 进行自增和对 j 进行自减操作。
  2. 函数参数列表中:

    • 在一些函数调用中,可以使用逗号运算符将多个参数连接起来传递给函数。
    • 例如:printf("%d, %d\n", a, (b = 5, b + 2));,这里先给 b 赋值为 5,然后计算 b + 2 的值为 7,最后将 a 的值和 7 依次传递给 printf 函数进行输出。
  3. 复杂表达式中:

    • 在一些复杂的表达式中,可以使用逗号运算符来组织多个子表达式,使代码更加清晰。
    • 例如:int result = ((a > b)? a : b, (c > d)? c : d);,这里先根据条件判断选择 ab 中的较大值,然后选择 cd 中的较大值,最后整个逗号表达式的值是 cd 中的较大值,所以 result 的值为 cd 中的较大值。

实例:

2,三目运算符

(1)、三目运算符的形式和作用
  1. 形式:

    • 表达式 1? 表达式 2 : 表达式 3。
  2. 作用:

    • 首先计算表达式 1,如果表达式 1 的值为真(非零值),则整个三目运算符的结果为表达式 2 的值;如果表达式 1 的值为假(零值),则整个三目运算符的结果为表达式 3 的值。

    • 例如:int max = (a > b)? a : b;,如果变量 a 的值大于变量 b 的值,那么 max 的值为 a;否则,max 的值为 b

(2)、三目运算符的应用场景
  1. 简洁的条件赋值:

    • 当需要根据一个条件进行赋值操作时,三目运算符可以提供一种简洁的方式。
    • 例如:int flag = (condition)? 1 : 0;,如果 condition 为真,则 flag 被赋值为 1;否则,flag 被赋值为 0。
  2. 在函数调用中:

    • 可以根据条件选择不同的函数参数进行函数调用。
    • 例如:printf("%s\n", (flag)? "True" : "False");,根据 flag 的值打印不同的字符串。
  3. 在表达式中简化条件判断:

    • 在一些复杂的表达式中,可以使用三目运算符来简化条件判断。
    • 例如:int result = (a > b)? (a + c) : (b + c);,根据 ab 的大小关系选择不同的表达式进行计算。
(3)、三目运算符的注意事项
  1. 可读性:

    • 虽然三目运算符可以使代码更加简洁,但在某些情况下,过度使用可能会降低代码的可读性。如果条件和结果表达式非常复杂,使用 if-else 语句可能会使代码更易于理解。
  2. 优先级:

    • 三目运算符的优先级较低,在复杂表达式中要注意使用括号来明确运算顺序,以避免出现意外的结果。

实例:

运行结果:

七,运算符的优先级

(这很关键)

|-----|--------------------------------------------------|------|
| 优先级 | 运算符 | 结合律 |
| 1 | 后缀运算符: [] () · -> ++ --(类型名称){列表} | 从左到右 |
| 2 | 一元运算符: ++ -- ! ~ + - * & sizeof_Alignof | 从右到左 |
| 3 | 类型转换运算符: (类型名称) | 从右到左 |
| 4 | 乘除法运算符: * / % | 从左到右 |
| 5 | 加减法运算符: + - | 从左到右 |
| 6 | 移位运算符: << >> | 从左到右 |
| 7 | 关系运算符: <<= >>= | 从左到右 |
| 8 | 相等运算符: == != | 从左到右 |
| 9 | 位运算符 AND: & | 从左到右 |
| 10 | 位运算符 XOR: ^ | 从左到右 |
| 11 | 位运算符 OR: | | 从左到右 |
| 12 | 逻辑运算符 AND: && | 从左到右 |
| 13 | 逻辑运算符 OR: || | 从左到右 |
| 14 | 条件运算符: ?: | 从右到左 |
| 15 | 赋值运算符: = += -= *= /= %= &= ^= |= <<= >>= | 从右到左 |
| 16 | 逗号运算符:, | 从左到右 |

Tips:

<1>表中优先级最高的运算符中的最后一个(类型名称) {列表} 是 C99 新增加的。

<2>一些运算符记号在表中出现了两次。例如,自增运算符 ++ 和自减运算符 --,在作后缀运算符(如表]达式 x++)时,较其用作前缀运算符(如表达式 ++x)时,具有较高的优先级。

<3>+、 -、 * 和 & 运算符记号不但可以当作一元运算符(unary operator,只需要一个操作数),也可以当作二元运算符(binary operator,需要两个操作数)。例如, * 只有一个操作数的时候,就是间接运算符(indirection operator),而有两个操作数的时候,就是乘号。

简单速记: ! > 算术运算 > 关系运算 > 逻辑运算 > 赋值运算

有个简单的小问题,思考一下:定义三个整数a,b,c,并从键盘进行赋值,然后进行排序。最终输出,a保存最小值, b保存其次, c保存最大值.

例如:

用户输入 a = 30,b = 20,c = 10.要求最终保存的结果为

a = 10,b = 20,c = 30

相关推荐
MengYiKeNan3 分钟前
C++二分函数lower_bound和upper_bound的用法
开发语言·c++·算法
会发paper的学渣9 分钟前
python 单例模式实现
开发语言·python·单例模式
学步_技术17 分钟前
Python编码系列—Python桥接模式:连接抽象与实现的桥梁
开发语言·python·桥接模式
柴华松20 分钟前
GPU训练代码
开发语言·python
好兄弟给我起把狙25 分钟前
[Golang] Select
开发语言·后端·golang
Echo_Lee028 分钟前
C#与Python脚本使用共享内存通信
开发语言·python·c#
python之行38 分钟前
python 环境问题
开发语言·python
小林熬夜学编程39 分钟前
C++第五十一弹---IO流实战:高效文件读写与格式化输出
c语言·开发语言·c++·算法
不是编程家1 小时前
C++ 第三讲:内存管理
java·开发语言·c++
尸僵打怪兽1 小时前
软考(中级-软件设计师)(0919)
java·c语言·数据库·计算机网络·软考·多媒体·软件设计师