C语言第三讲——程序运算符

简介: C语言第三讲——程序运算符

运算符

计算机中的运算符包含 +-*/%五种,这五种运算符分别是数学里面的加减乘除和取模。

运算顺序

在计算机编程中,运算符具有不同的优先级,这些优先级决定了表达式中运算符的执行顺序。在常见的运算符中,乘法(*)和除法(/)的优先级比加法(+)和减法(-)高,取余运算符(%)的优先级也较高。当然,括号具有最高的优先级,它们用于改变标准的运算顺序。具体来说,运算符的执行顺序如下:

  1. 括号 (): 括号中的表达式具有最高的优先级,会首先被计算。
  2. 乘法 *,除法 / 和取余 %: 这些运算符的优先级次之,会在没有括号的情况下,按照从左到右的顺序进行计算。如果一个表达式中包含多个乘法、除法或取余运算符,它们将按照从左到右的顺序依次执行。
  3. 加法 + 和减法 -: 这两个运算符的优先级最低,会在没有括号、乘法、除法或取余运算的情况下,按照从左到右的顺序进行计算。

为了更好地控制运算符的执行顺序,程序员可以使用括号来明确指定表达式的计算顺序。例如,如果有一个表达式 a + b * c,由于乘法运算符的优先级高于加法运算符,所以会先计算 b * c,然后再将 a 与结果相加。但是,如果表达式是 (a + b) * c,那么括号中的部分会先被计算,然后再与 c 相乘。

总结起来,括号具有最高的优先级,然后是乘法、除法和取余运算符,最后是加法和减法运算符

使用注意事项

加法 + 和减法 - 运算符

  • 加法运算符 + 用于加法操作,例如 a + b
  • 减法运算符 - 用于减法操作,例如 a - b
  • 注意数据类型:在一些编程语言中,+ 运算符也可以用于字符串的拼接(字符串连接),需要确保操作数的数据类型兼容。

乘法 *,除法 / 和取余 % 运算符

  • 乘法运算符 * 用于乘法操作,例如 a * b
  • 除法运算符 / 用于除法操作,例如 a / b。需要注意除数不能为零,否则会引发错误。
  • 取余运算符 % 返回除法的余数,例如 a % b。取余操作要求除数不能为零。同时,取余运算的两边只能是整数。

括号 () 运算符

  • 括号用于控制运算符的优先级,括号内的表达式会先于其他运算符被计算。例如,(a + b) * c 会先计算括号内的加法,然后再与 c 相乘。

其余事项

  • 数据类型一致性:确保参与运算的操作数具有相同或兼容的数据类型。不同的数据类型可能在运算时会有不同的行为,例如整数和浮点数的除法结果可能不同。
  • 溢出问题:在使用整数运算时,要注意可能导致的溢出问题。如果运算结果超出了数据类型的表示范围,可能会导致错误的结果。
  • 浮点数精度:浮点数在计算机中通常无法精确表示,可能存在精度丢失问题。在比较浮点数是否相等时,应该使用范围或误差容忍度。
  • 除零错误:除数不能为零。在除法运算前,应该检查除数是否为零,以避免程序运行时错误。
  • 代码可读性:为了提高代码的可读性和可维护性,建议在表达式中适当使用括号,即使它们并不改变运算顺序,也能使代码更清晰明了。

比较运算符

比较运算符包含 ><>=<=!===等等,和我们数学里面其实是一样的。

注意事项

在C语言中,比较运算符(><>=<=!===)用于比较两个表达式的关系,返回一个布尔值(1表示真,0表示假)。在使用这些比较运算符时,有一些注意事项:

数据类型一致性

比较运算符的操作数应该是相同或兼容的数据类型。比如,你不能比较一个整数和一个字符指针,除非你进行了适当的类型转换。

注意逻辑操作符的优先级

比较运算符的优先级低于算术运算符,但高于赋值运算符。因此,在复杂的表达式中,确保使用括号来明确运算顺序,以避免混淆。

例如,a + b > c * d 会先计算 a + bc * d,然后再进行比较。如果你的意图是比较 a + bc * d 的和,你应该使用括号:(a + b) > (c * d)

不等于运算符 != 和等于运算符 ==

  • != 表示不等于,用于判断两个值是否不相等。
  • == 表示等于,用于判断两个值是否相等。

谨慎使用浮点数比较

在C语言中,由于浮点数的精度问题,避免直接使用等于运算符(==)来比较两个浮点数是否相等。应该使用一个误差范围(epsilon)来比较,例如:

#include <math.h>
#define EPSILON 0.000001

if (fabs(a - b) < EPSILON) {
    // a 和 b 在误差范围内相等
}

这里 fabs() 函数用于返回一个浮点数的绝对值。

字符比较

字符在C语言中是整数类型,可以用比较运算符进行比较。例如,'a' < 'b' 是一个合法的表达式。

避免混淆

在复杂的表达式中,使用括号可以增加可读性,防止比较运算符的优先级导致混淆。

布尔表达式

比较运算符通常用于构建布尔表达式,用于控制程序的流程,例如在条件语句(if语句、循环等)中。

逻辑运算符

逻辑运算符包含 && 逻辑与,||逻辑或,!逻辑非。

用法

逻辑运算符(&&||!)在C语言中用于处理布尔值(truefalse)的逻辑操作。这些运算符允许你在条件语句、循环和其他控制结构中构建复杂的逻辑表达式。

  1. 逻辑与 &&
  • && 表示逻辑与运算符,用于判断两个条件是否同时为真(非零)。
  • 如果两个操作数都为真,&& 运算符返回真;如果任何一个操作数为假,它就返回假。
  • 示例:if (a > 0 && b > 0) 表示当 ab 同时大于零时条件成立。
  1. 逻辑或 ||
  • || 表示逻辑或运算符,用于判断两个条件中是否至少有一个为真(非零)。
  • 如果两个操作数中任何一个为真,|| 运算符返回真;只有当两个操作数都为假时,它才返回假。
  • 示例:if (x == 0 || y == 0) 表示当 x 或者 y 中至少有一个为零时条件成立。
  1. 逻辑非 !
  • ! 表示逻辑非运算符,用于取反一个条件的值。如果条件为真,则取反后为假;如果条件为假,则取反后为真。
  • 示例:if (!(a > 0)) 表示当 a 不大于零时条件成立。

注意事项

短路评估(Short-Circuit Evaluation)

在逻辑与 && 和逻辑或 || 运算中,C语言采用短路评估。这意味着,如果在逻辑与运算中第一个操作数为假,整个表达式必定为假,因此第二个操作数将不会被评估。同样,在逻辑或运算中,如果第一个操作数为真,整个表达式就为真,第二个操作数也不会被评估。这个特性可以用于编写更加高效的代码。

正确使用括号

在复杂的逻辑表达式中,合理使用括号来明确运算顺序,提高表达式的可读性和可维护性。

避免混淆

当逻辑表达式变得非常复杂时,很容易混淆。建议使用括号明确运算顺序,以避免逻辑错误。

避免在非布尔类型上使用逻辑运算符

虽然在C语言中,非零值被视为真,零被视为假,但最好在逻辑运算符上使用明确的布尔值,以避免不必要的麻烦和混淆。

赋值运算的缩写

在C语言中,+=-=/=%=*= 等缩写形式是赋值运算符的扩展。它们用于将运算结果赋给左侧的操作数,并且这种写法使得代码更加简洁和可读。

基本用法

+= (加法赋值运算符)

a += b 等价于 a = a + b。这个操作将变量 a 的值增加 b 的值,并将结果赋给 a

-= (减法赋值运算符)

a -= b 等价于 a = a - b。这个操作将变量 a 的值减去 b 的值,并将结果赋给 a

*= (乘法赋值运算符)

a *= b 等价于 a = a * b。这个操作将变量 a 的值乘以 b 的值,并将结果赋给 a

/= (除法赋值运算符)

a /= b 等价于 a = a / b。这个操作将变量 a 的值除以 b 的值,并将结果赋给 a

%= (取余赋值运算符)

a %= b 等价于 a = a % b。这个操作将变量 a 的值除以 b 的值得到余数,并将余数赋给 a

这些缩写形式通常在需要更新变量的值时使用,可以使代码更简洁、易读。例如,如果要将一个变量递增1,可以使用 x += 1,而不是 x = x + 1

注意事项

  1. 数据类型一致性:确保左右操作数的数据类型一致或兼容。例如,如果 a 是整数类型,b 是浮点数类型,在 a += b 操作中,b 的值会被截断成整数,可能导致精度损失。
  2. 避免副作用:当使用这些缩写形式时,确保不会引起不必要的副作用。例如,避免在同一个表达式中多次修改同一个变量的值,以免引起不明确的行为。
  3. 注意溢出:在涉及整数运算时,注意防止溢出。如果结果超出了变量的数据类型所能表示的范围,可能会得到不正确的结果。
  4. 增强可读性:虽然这些缩写形式可以使代码更简洁,但在某些情况下,使用完整形式可能会增强代码的可读性,特别是在复杂的表达式中。选择使用哪种形式通常取决于代码的清晰度和可维护性。
  5. b是一个整体:例如我们将 a/=b-c 恢复成原样的结果应该是a = a/(b-c),即我们看到的右侧是一个整体进行运算,故在进行完整化时应该打上括号。

++和--

++-- 是C语言中的递增和递减运算符,它们用于增加或减少变量的值。这两个运算符分别表示递增和递减,是一种非常方便的操作符,特别在循环结构和条件语句中经常被使用。

  • ++ 是递增运算符,用于将变量的值加1。例如,x++ 等价于 x = x + 1
  • -- 是递减运算符,用于将变量的值减1。例如,y-- 等价于 y = y - 1

与赋值运算符一起的时候放在,前置和后置的区别

这两个运算符可以用在变量的前面(前缀形式)或后面(后缀形式),在前缀形式中,变量的值会在运算之前被改变,而在后缀形式中,变量的值会在运算之后被改变。

例如:


int x = 5;
int y = 10;

int a = ++x; // 前缀递增,a的值为6,x的值为6
int b = y--; // 后缀递减,b的值为10,y的值为9

注意事项

  1. 副作用:递增和递减运算符会改变变量的值,因此在使用它们时需要小心,确保不会引起不必要的副作用。避免在同一语句中多次修改同一个变量的值,以免引起不明确的行为。
  2. 位置的影响:前缀形式和后缀形式的区别在于运算符的位置。在表达式中的位置可能会影响程序的行为,尤其是在复杂的表达式中。例如,int a = 5; int b = ++a * 2;int a = 5; int b = a++ * 2; 的结果是不同的。
  3. 可读性:递增和递减运算符的使用可能增加代码的紧凑性,但有时也可能降低可读性。在编写代码时,应该权衡代码的紧凑性和可读性,选择最适合上下文的形式。

按位运算

在C语言中,按位运算是对整数类型的数据在二进制位上进行位操作的运算。主要的按位运算符包括位与(&)、位或(|)、位异或(^)、取反(~)、左移位(<<)和右移位(>>)。

用法

位与运算符 &

  • & 运算符用于对两个数的每个对应位执行与操作。如果两个操作数的对应位都为1,结果位为1;否则结果位为0。
  • 示例:a & b 将返回 ab 的按位与结果。

位或运算符 |

  • | 运算符用于对两个数的每个对应位执行或操作。如果两个操作数的对应位中至少有一个为1,结果位为1;否则结果位为0。
  • 示例:a | b 将返回 ab 的按位或结果。

位异或运算符 ^

  • ^ 运算符用于对两个数的每个对应位执行异或操作。如果两个操作数的对应位不相同,结果位为1;如果相同,结果位为0。
  • 示例:a ^ b 将返回 ab 的按位异或结果。

取反运算符 ~

  • ~ 运算符用于对操作数的每个位执行取反操作,即将1变为0,0变为1。
  • 示例:~a 将返回 a 的按位取反结果。

左移位运算符 <<

  • << 运算符将操作数的所有位向左移动指定的位数。左移n位相当于乘以2的n次方。
  • 示例:a << n 将返回 a 左移n位的结果。

右移位运算符 >>

  • >> 运算符将操作数的所有位向右移动指定的位数。右移n位相当于除以2的n次方,但在负数的情况下可能有符号扩展。
  • 示例:a >> n 将返回 a 右移n位的结果。

注意事项

  1. 数据类型:按位运算符通常用于整数类型的数据,尤其是无符号整数。在使用位运算符时,确保操作数的数据类型是符合预期的。
  2. 位移位数:在进行左移和右移操作时,确保指定的位数在合理范围内,避免超出数据类型的位数范围,导致意外的结果。
  3. 符号扩展:在右移操作中,对于有符号整数,可能会进行符号扩展,即用符号位填充左侧的空位。这可能导致负数的结果不同于预期,因此在右移有符号整数时要特别注意。
  4. 可读性和效率:虽然位运算可以用于提高程序的执行效率,但在编写代码时,也要考虑代码的可读性。有时候,使用更直观的表达式可能比使用位运算更容易理解。在选择使用位运算时,要确保它们的应用场景明确,并且能够提供性能上的实际改进。

三目运算符

在C语言中,三目运算符(也称为条件运算符)是一种非常简洁的条件表达式。它使用问号 ? 和冒号 : 来表示。三目运算符的语法结构如下:

condition ? expression1 : expression2;

它的含义是,如果 condition 表达式的值为真(非零),则整个表达式的值为 expression1 的值;否则,整个表达式的值为 expression2 的值。

例如,以下的表达式使用了三目运算符:

int a = 5;
int b = 10;
int max = (a > b) ? a : b;

在这个例子中,(a > b) 是条件表达式,如果 a 大于 b,则 max 的值为 a;否则,max 的值为 b

三目运算符的优点在于它非常简洁,可以在一行代码中完成条件判断和赋值操作。但是,为了保持代码的可读性,它应该适度使用,避免嵌套过多,以免降低代码的可读性。

数据类型转换

原则

在C语言中,数据类型转换是将一个数据类型的值转换为另一个数据类型的过程。C语言中的数据类型转换原则主要有以下几点:

  1. 隐式类型转换(自动类型转换)
  • 在某些情况下,C语言会自动进行数据类型转换,而不需要程序员显式地指定。这种转换被称为隐式类型转换。
  • 例如,当不同类型的操作数混合运算时,C语言会自动将其中一个操作数转换为更大的数据类型,以避免精度损失。例如,在整数和浮点数之间的运算中,整数通常会被自动转换为浮点数。
  1. 显式类型转换(强制类型转换)
  • 程序员可以使用强制类型转换(也称为显式类型转换)来将一个数据类型转换为另一个数据类型。
  • 强制类型转换使用括号和目标数据类型,例如 (int) x 将变量 x 转换为整数类型。这种转换通常被用来处理特定的需求,但要谨慎使用,避免造成数据丢失或误解。
  1. 数据精度损失
  • 在进行数据类型转换时,要注意可能引起的数据精度损失。例如,将一个浮点数转换为整数时,小数部分会被截断,可能导致精度损失。
  • 要确保转换不会导致数据失真或不正确的结果。
  1. 整数提升
  • 在表达式中,较小的整数类型(如charshort)会被自动提升为较大的整数类型(如int),以进行运算。这种提升是为了避免小整数类型的溢出。
  1. 符号扩展
  • 在进行整数类型转换时,如果从有符号整数类型转换为无符号整数类型,或者从较小的有符号整数类型转换为较大的有符号整数类型,可能发生符号扩展。符号扩展是指在将有符号整数类型转换为更大的类型时,使用符号位进行填充。程序员应该注意符号扩展可能引起的意外结果。

在C语言中,将int型转换成浮点型也可以让int型乘以1.0实现。

目录
相关文章
|
存储 C语言 C++
【c语言】运算符汇总(万字解析)
今天博主跟大家分享了c语言中各种操作符的功能、使用方法以及优先级和结合性,并且与大家深入探讨了表达式求值的两个重要规则--算数转换和整形提升。学习这些知识对我们的C语言和C++学习都有着极大的帮助。
1202 2
|
存储 自然语言处理 编译器
【C语言】编译与链接:深入理解程序构建过程
【C语言】编译与链接:深入理解程序构建过程
279 2
|
人工智能 Java 程序员
一文彻底搞清楚C语言的运算符
本文详细介绍了C语言中的各类运算符,包括算术、关系、逻辑、位运算符、赋值、三目运算符及sizeof,帮助读者深入理解其用法与特性。君志所向,一往无前,希望在成长的路上有你相伴!
1627 2
一文彻底搞清楚C语言的运算符
|
C语言
C语言判断和运算符联系
在 C 语言中,判断与运算符紧密相关,主要体现在条件表达式的使用上。
425 87
|
安全 C语言
C语言运算符的使用注意点
在C语言中,正确使用运算符能提升代码的可读性和效率。本文介绍了八大注意事项:运算符优先级和结合性影响运算顺序;自增/自减运算符分前缀和后缀形式;逻辑运算符有短路特性;位运算符直接操作二进制位需谨慎;条件运算符简洁但避免复杂嵌套;类型转换避免意外结果;使用括号明确运算顺序。掌握这些要点有助于编写更安全高效的代码。
623 72
|
C语言
【C语言】条件运算符详解 - 《 A ? B : C 》
条件运算符(也称为三元运算符)是C语言中唯一的三元运算符。它通常用于替代简单的 `if-else` 语句。
1442 6
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
528 5
|
C语言
C语言编程中,错误处理至关重要,能提升程序的健壮性和可靠性
C语言编程中,错误处理至关重要,能提升程序的健壮性和可靠性。本文探讨了C语言中的错误类型(如语法错误、运行时错误)、基本处理方法(如返回值、全局变量、自定义异常处理)、常见策略(如检查返回值、设置标志位、记录错误信息)及错误处理函数(如perror、strerror)。强调了不忽略错误、保持处理一致性及避免过度处理的重要性,并通过文件操作和网络编程实例展示了错误处理的应用。
520 4
|
网络协议 物联网 数据处理
C语言在网络通信程序实现中的应用,介绍了网络通信的基本概念、C语言的特点及其在网络通信中的优势
本文探讨了C语言在网络通信程序实现中的应用,介绍了网络通信的基本概念、C语言的特点及其在网络通信中的优势。文章详细讲解了使用C语言实现网络通信程序的基本步骤,包括TCP和UDP通信程序的实现,并讨论了关键技术、优化方法及未来发展趋势,旨在帮助读者掌握C语言在网络通信中的应用技巧。
559 2
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
624 1