C语言基础内容(三)——第03章_运算符与流程控制

发布时间:2024年01月11日

第03章_运算符与流程控制

本章专题脉络

在这里插入图片描述

1. 运算符(Operator)

运算符是一种特殊的符号,用以表示数据的运算、赋值和比较等。

运算符的分类:

  • 按照功能分为:算术运算符、赋值运算符、比较(或关系)运算符、逻辑运算符、位运算符、条件运算符、sizeof运算符
分类 运算符
算术运算符 +、-、+、-、*、/、%、++、–
赋值运算符 =、+=、-=、*=、/=、%=等
比较(或关系)运算符 >、>=、<、<=、==、!=
逻辑运算符 &&、||、!
位运算符 &、|、^、~、<<、>>
条件运算符 (条件表达式)?结果1:结果2
sizeof运算符 sizeof()
  • 按照操作数个数分为:一元运算符(单目运算符)、二元运算符(双目运算符)、三元运算符 (三目运算符)
分类 运算符
一元运算符(单目运算符) 正号(+)、负号(-)、++、–、!、~
二元运算符(双目运算符) 除了一元和三元运算符剩下的都是二元运算符
三元运算符 (三目运算符) (条件表达式)?结果1:结果2

1.1 算术运算符

算术运算符专门用于算术运算,主要有下面几种。
在这里插入图片描述举例1:

float x = 6 / 4;
printf("%f\n", x); // 输出 1.000000

float x = 6.0 / 4; // 或者写成 6 / 4.0
printf("%f\n", x); // 输出 1.500000

举例2:%,运算结果的符号与被模数相同

int x1 = 6 % 4; // 2
int x2 = -6 % 4; // -2
int x3 = 6 % -4; // 2
int x4 = -6 % -4; // -2

举例3:自加自减运算

理解:++ 运算,表示自增1。同理,-- 运算,表示自减1,用法与++ 一致。

1、单独使用

  • 变量在单独运算的时候,变量前++和变量后++,是没有区别的。
  • 变量前++ :例如 ++a
  • 变量后++ :例如 a++

2、复合使用

  • 其他变量放在一起使用或者和输出语句放在一起使用前++后++就产生了不同。
  • 变量前++ :变量先自增1,然后再运算。
  • 变量后++ :变量先运算,然后再自增1。
int main() {
   
    // 其他变量放在一起使用
    int x = 3;
    //int y = ++x; // y的值是4,x的值是4,
    int y = x++; // y的值是3,x的值是4

    printf("%d\n",x);
    printf("%d\n",y);
    printf("==========\n");

    // 和输出语句一起
    int z = 5;
    //printf("%d\n",++z);// 输出结果是6,z的值也是6
    printf("%d\n",z++);// 输出结果是5,z的值是6
    printf("%d\n",z);

    return 0;
}

与此对应的:

  • 变量前-- :变量先自减1,然后再运算。
  • 变量后-- :变量先运算,然后再自减1。

1.2 赋值运算符

  • 符号 =
    • 当“=”两侧数据类型不一致时,可以使用自动类型转换或使用强制类型转换原则进行处理。
    • 支持连续赋值
  • 扩展赋值运算符: +=、 -=、*=、 /=、%=
运算符 名称 实例 展开形式
+= 复合加赋值 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

1.3 比较运算符(或关系运算符)

常用的比较运算符:

关系运算符 含义 举例
> 大于 num > 10
>= 大于等于 num >= 10
< 小于 num < 10
<= 小于等于 num <= 10
== 等于 num == 10
!= 不等于 num != 10
  • 比较运算的结果只有两个取值,要么是真(非0 表示,默认使用1),要么是假(0 表示)。
    • 比如, 20 > 12 返回 1 , 12 > 20 返回 0 。
  • 比较运算符“==”不能误写成“=

举例:多个关系运算符不宜连用。

i < j < k   //期望判断j是否大于i,且小于k

这是合法表达式,不会报错,但是通常达不到想要的结果,即不是保证变量 j 的值在 i 和 k 之间。比如:

//i < j < k
int j = 10;
if(15 < j < 20){
   
    printf("j大于15,且小于20"); //输出此语句
}else{
   
    printf("j不在15到20之间");
}

因为关系运算符是从左到右计算,所以实际执行的是:

(i < j) < k; //i < j 返回 0 或 1 ,所以最终是 0 或 1 与变量 k 进行比较

期望的效果应该写为:

//i < j < k
int j = 10;
if(15 < j && j < 20){
   
    printf("j大于15,且小于20"); 
}else{
   
    printf("j不在15到20之间"); //输出此语句
}

1.4 逻辑运算符

主要有下面三个运算符:

逻辑运算符 描述 功能 举例
&& 与运算符 两个条件都要满足 num1 >= 10 && num2 >= 20
|| 或运算符 两个条件只需满足其一 num1 >= 10 || num2 >= 20
! 非运算符 否定条件 !(num1 >= 10)(等价于 num1 < 10)

逻辑运算符提供逻辑判断功能,用于构建更复杂的表达式。

举例:

a b a && b a || b !a
1(真) 1(真) 1(真) 1(真) 0(假)
1(真) 0(假) 0(假) 1(真) 0(假)
0(假) 1(真) 0(假) 1(真) 1(真)
0(假) 0(假) 0(假) 0(假) 1(真)

对于逻辑运算符来说,任何非零值都表示真,零值表示伪。比如, 5 || 0 会返回 1 , 5 && 0 会返回0 。

举例1:短路现象

  • &&:a && b
    • 当 a 为假(或0)时,因为a && b 结果必定为 0,所以不再执行表达式 b
    • 当 a 为真(非0)时,因为a && b 结果不确定,所以会继续求解表达式b
int i = 0;
int j = 10;
if(i && j++ > 0){
   
    printf("床前明月光");
}else{
   
    printf("我叫郭德纲");
}

printf("%d\n",j); //10

  • || :a || b
    • 当 a 为真(非0)时,因为a || b 结果必定为 1,所以不再执行表达式 b
    • 当 a 为假(或0)时,因为a || b 结果不确定,所以会继续求解表达式b
int i = 1;
int j = 10;
if(i || j++ > 0){
   
    printf("床前明月光");
}else{
   
    printf("我叫郭德纲");
}

printf("%d\n",j); //10

1.5 位运算符

  • C 语言提供一些位运算符,用来操作二进制位(bit)。
  • 位运算符的运算过程都是基于二进制的补码运算。
运算符 描述 运算规则
<< 二进制左移 将一个数的各二进制位全部左移指定的位数,左边的二进制位丢弃,右边补0。
>> 二进制右移 将一个数的各二进制位全部右移指定的位数,正数左补0,负数左补1,右边丢弃。
& 按位与 两个二进制位都为 1,结果为1,否则为0。
| 按位或 两个二进制位只要有一个为1(包含两个都为 1 的情况),结果为1,否则为0。
^ 按位异或 两个二进制位一个为0,一个为1,结果为1,否则为0。
~ 按位取反 将每一个二进制位变成相反值,即 0 变成 1 , 1 变成 0 。
  • 结合赋值运算符的经验,这里有:<<= 、 >>= 、 &= 、 ^= 等

举例1:

(1)左移:<<

运算规则:在一定范围内,数据每向左移动一位,相当于原数据*2。(正数、负数都适用)

【注意】当左移的位数n超过该数据类型的总位数时,相当于左移(n-总位数)位

3<<4  类似于  3*24次幂 => 3*16 => 48

在这里插入图片描述

-3<<4  类似于  -3*24次幂 => -3*16 => -48

在这里插入图片描述

(2)右移:>>

运算规则:在一定范围内,数据每向右移动一位,相当于原数据/2。(正数、负数都适用)

【注意】

1、如果不能整除,向下取整

2、右移运算符最好只用于无符号整数,不要用于负数。因为不同系统对于右移后如何处理负数的符号位,有不同的做法,可能会得到不一样的结果。

69>>4  类似于  69/24次幂 = 69/16 =4

在这里插入图片描述

-69>>4  类似于  -69/24次幂 = -69/16 = -5

在这里插入图片描述

练习:高效的方式计算2 * 8的值(经典面试题)

答案:2 << 3 、  8  << 1

举例2:

(1)按位与:&

运算规则:对应位都是1才为1,否则为0。

  • 1 & 1 结果为1
  • 1 & 0 结果为0
  • 0 & 1 结果为0
  • 0 & 0 结果为0
9 & 7 = 1

在这里插入图片描述

-9 & 7 = 7

在这里插入图片描述
(2)按位或:|

运算规则:对应位只要有1即为1,否则为0。

  • 1 | 1 结果为1
  • 1 | 0 结果为1
  • 0 | 1 结果为1
  • 0 & 0 结果为0
9 | 7  //结果: 15

在这里插入图片描述

-9 | 7 //结果: -9

在这里插入图片描述(3)按位异或:^

运算规则:对应位一个为1一个为0,才为1,否则为0。

  • 1 ^ 1 结果为0
  • 1 ^ 0 结果为1
  • 0 ^ 1 结果为1
  • 0 ^ 0 结果为0
9 ^ 7  //结果为14

在这里插入图片描述

-9 ^ 7 //结果为-16

在这里插入图片描述(4)按位取反:~

运算规则:对应位为1,则结果为0;对应位为0,则结果为1。

  • ~0就是1
  • ~1就是0
~9  //结果:-10

在这里插入图片描述

~-9  //结果:8

在这里插入图片描述练习:特定位清零

技巧:待清零的位与0,其它位与1

示例:设字符型 x 的当前值为 53,将其最低两位清 0,其余位保持不变

分析:与二进制的0b11111100数值求&运算即可。

int main() {
   
    char x = 53; // 0b00110101
    x = x & 252; // 0b11111100
    printf("%d", x); //0b00110100
    return 0;
}

举例:判断特定位是否为零

技巧:待判定位与 1,其它位与 0;判与运算结果是否为 0

示例:设字符型 x 的当前值为 53,判定其最高位是否为 0

分析:与二进制的0b10000000求&运算,若结果为 0,则最高位为 0,否则为 1

int main() {
   
    char x 
文章来源:https://blog.csdn.net/sun7_9/article/details/135440329
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。