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实现。

目录
相关文章
|
1月前
|
C语言
最简单的C语言程序示例
最简单的C语言程序示例
20 0
|
1月前
|
Serverless C语言
C语言程序通常具有以下基本结构
C语言程序通常具有以下基本结构
10 0
|
1月前
|
C语言 C++
第一个c语言程序
第一个c语言程序
|
1月前
|
Java 编译器 C语言
【JavaSE】运算符详解及与C语言中的区别
【JavaSE】运算符详解及与C语言中的区别
48 0
|
1月前
|
存储 程序员 C语言
C语言强制类型转换运算符
C语言强制类型转换运算符
12 1
|
13天前
|
存储 编译器 C语言
深入探索C语言动态内存分配:释放你的程序潜力
深入探索C语言动态内存分配:释放你的程序潜力
26 0
|
1月前
|
C语言
C语言最基本程序控制结构
C语言最基本程序控制结构
14 0
|
30天前
|
存储 Serverless C语言
C语言程序的结构
C语言是一种广泛使用的编程语言,其程序结构清晰,易于理解。下面我们将详细探讨C语言程序的基本结构,并通过一个示例代码来展示这些组成部分是如何协同工作的。 一、C语言程序的基本结构
14 0
|
30天前
|
编译器 C语言
C语言中的运算符
在C语言中,运算符是一种告诉编译器执行特定数学或逻辑操作的符号。这些运算符可以与一个或多个变量组合在一起,形成一个表达式。C语言支持多种类型的运算符,包括算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符和条件运算符等。
16 0
|
30天前
|
程序员 C语言
最简单的C语言程序举例
C语言是一种广泛使用的计算机编程语言,适合用于系统编程,也可以用于编写应用程序。它的语法清晰明了,功能强大,是很多程序员的首选语言。下面,我们将通过一个最简单的C语言程序来介绍其基本结构和语法。
26 0