嵌入式开发学习(C语言基础)

运算符

赋值运算符

“="称之为赋值运算符,其作用是将一个数据赋值给一个变量,如:int a = 5 ;

执行赋值运算的结果,是将右边的数据存入左边变量对应的内存单元,赋值运算的顺序:自左向右

赋值规则

如果赋值运算符两侧的类型不一致,在赋值时进行类型转换,转换规则:

  • 浮点型→类型变量:舍弃小数部分。如(int a= 5.5 → a =5
  • 整型→浮点型变量:数值不变,以浮点型存储。如:(double a = 5 → a = 5.000000...
  • 字符型→整型变量:放在整型的第8位,保持原值不变规则。(如int a = 'A'

在这里插入图片描述

赋值表达式

实现赋值运算的表达式:

语法:

变量 = 表达式 ;

案例:

a = 5;        //将一个int类型的常量(字面量)赋值给一个int类型变量,解释:字面量就是常量的一种
y = 2 * x + 3;//将一个表达式运算的结果赋值给变量
a = a + 1;    //将一个表达式运算的结果复制给变量

作用:

将右边表达式的值赋值给左边的变量。赋值表达式的取值取自左边变量的值。

什么是表达式?

​ 表达式=运算数+运算符

什么是运算数?

​ 常量、变量、表达式都可以是运算数。

复合赋值运算符

+= 、-=、 *=、 /=、 %=...、&= 、|= 、>>=、 <<=、 ~= 、^=

int a = 1;
a += 3;   //等价于 a = a + 3;

int c = 2;
c /=c;    //等价于 c = c / c; c = 2 / 2; c = 1;

// ...其他复合运算符使用同理

注意:

①在运算时:不能将(=)写作(==)

②赋值运算符的优先级属于最低(除了逗号运算符以外)(a+b)/c,一般都是留到最后运算

关系运算符

>、<、>=、<=、==、!=、

  • 所有的关系运算符都是双目运算符(二元运算符),运算符的左侧和右侧可以是变量、可以是常量(字面量、符号常量、使用const修饰的变量)、还可以是表达式。举例:a > b,5 > 6, a+b > c

  • 关系运算符运算结果的布尔类型,C语言中的布尔类型使用整型int来表示,使用非0作为真,使用0作为假。

    int a = 5; b = 4;
    printf("%d,%d\n",a > b;a+b > 10);//1,0  计算机底层:1-真,0-假
    

C99标准引入stdbool.h库本质上是对0和1进行了封装。其实很简单,就是定义了两个符号常量:

#define ture 1
#define flase 0

注意:

  • 避免链式使用(如:0 <= score <= 100),应该改为逻辑与:score >= 0 && score <= 100

    int score1 = 45,score2 = -65,score3 = 110;
    printf("%d\n",0 <= score1 <= 100);//0 <= score1 → 1 <= 100 → 1 最终结果是真,45在 0~100之间,成立 
    printf("%d\n",0 <= score2 <= 100);//0 <= score2 → 1 <= 100 → 1 最终结果是真,-65在 0~100之间,成立?
    printf("%d\n",0 <= score3 <= 100);//0 <= score3 → 1 <= 100 → 1 最终结果是真,110在 0~100之间,成立?
    

    经过以上测试,我们发现链式比较语法上没有问题,可以通过编译,但是逻辑上有问题,所以不能用作条件判断。

  • 浮点数比较需要差值法fabs(a - b)<1e-6 0.000001。使用fabs 取绝对值函数,需要引入**math.h**

    3.000 000可以认为和3.000 001相等

    /*************************************************************************
      > File Name:    demo01.c
      > Author:       小刘
      > Description:  
      > Created Time: 2025年05月06日 星期二 09时24分10秒
     ************************************************************************/
    
    #include <stdio.h>
    
    int main(int argc,char *argv[])
    {
        float a = 0.1f + 0.2f;
        float b = 0.3f;
    
        printf("0.1 +0.2 = %.20f\n",a);//%.20f 意思是小数点保留20位
        printf("     0.3 = %.20f\n",b);
    
        double a1 = 0.1 * 2;
        printf("%d\n",a1 == 0.2);
        return 0;
    }
    
    

    总结:

    操作正确方式错误方式
    浮点数相等比较使用误差范围(fabs(a - b) < epsilona == b
    浮点数大小比较直接使用 > 或 < (误差不影响顺序)-
    零比较fabs(a ) < epsilona == 0.0

逻辑运算符

运算的结果为布尔值,要么为真(非0),要么为假(0)

  • !:非(逻辑非)单目运算符,并且只能在操作数左侧;非真即为假、非假即为真。(取反)

    • 对于一个数或者表达式取非奇数次,结果与原值相反(奇变偶),!(a%2!=0)取偶次数
    • 对于一个数或者表达式取非偶数次,结果与原值相反(偶变奇),!(a%2!=0)取奇次数
  • &&:==与(逻辑与)==双目运算符,当左右两侧的数据都为真时,最终的结果才为真(有假则为假)

    当逻辑运算时,左侧为假,右侧结果不会影响最终结果,右侧不会执行,最终结果就是左侧的结果(假),这种现象称之为短路效果(短路与),这是C语言中提供的一种惰性计算,就是为了减少运算次数。

    案例:

    //需求:要求成绩在0~100以内
    int score = 90;
    score >= 0 && score <= 100;//1
    
  • ||:==或(逻辑与或)==双目运算符,当左右两侧的数据都为假时,最终的结果才为假(有真则为真)

    当逻辑运算时,左侧为真,右侧结果不会影响最终结果,右侧不会执行,最终结果就是左侧的结果(真),这种现象称之为短路效果(短路或),这是C语言中提供的一种惰性计算,就是为了减少运算次数。

    案例:

    //需求:闰年计算公式
    int year = 2025;
    (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)
    

逗号运算符

**作用:**将若干个表达式“串联起来”,如:a = 4, a+=3;

**别称:**顺序求值运算符

逗号表达式

语法:

表达式1,表达式2,...表达式n,

**求解过程:**按从从左到右

案例:

#include<stdio.h>

int main()
{
    int a = 0, b = 0;
    
    //逗号表达式
    int result = (a = 3,b = 5,a + b);//整体是赋值表达式
    //怎么判断一个表达式是逗号还是赋值表达式,要是它最终的运算是赋值操作还是逗号操作
    
    //结合条件判断
    int x = 10, y = 20;
    int max = (x++, y++,(x>y) ? x : y);//x = 11, y = 21, max = 21
    
    printf("result=%d,max=%d\n",result,max);//result=8,max=21
    
    return 0;
}

位运算

说明:按位(bit)来进行运算操作的运算符,更多时候用于嵌入式开发。

语法:~、&、|、^、<<、>>

~:按为取反

说明:单目运算符,数据每一个bit位按位取反,也就是二进制数据位上,0变成1,1变成0。

演示:

在这里插入图片描述

举例:

unsigned char ret = ~0x05;
printf("%d\n",~5);
&:按位与

说明:双目运算符,对于运算符左右的两个数,对应二进制位数据都为1时,结果为1,否则为0

演示:

在这里插入图片描述

举例:

printf("%d\n",5 & 6);//4
|:按位或

说明:双目运算符,对于运算符左右两个数,对应二进制位数据有一个1则为1,否则为0

演示:

在这里插入图片描述

举例:

printf("%d\n",5|6);//?
^:按位异或

说明:双目运算符,对于运算符左右的两个数,对应的二进制数据相同,结果为0,不同则为1

演示:

在这里插入图片描述

举例:

printf("%d\n",5 ^ 6);// 3
<<:左移,按位左移

说明:原操作数所有二进制位数想左移整体移动指定位。(高舍低补)

无符号左移;
  • 语法:
操作数 << 移动位数
  • 举例:
unsigned int a = 3 << 3;//24 将3左移3位,可以套用公式:3 * 2 ^ 3
unsigned int b = 5 << 4;//80 将5左移4位,可以套用公式:5 * 2 ^ 4

在这里插入图片描述

有符号左移:
  • 语法:

    操作数 << 移动位数
    
  • 举例:

int a = -3 << 3;//-24 将-3左移3位,可以套用公式:-3 * 2 ^ 3
int b = 240 << 2;///960 将240左移2位,可以套用公式:240 * 2 ^ 2
  • 注意:
    • 如果移除的高位都是0,我们可以这样理解:a << n,可以看做是 a ∗ 2 n a*2^n a2n
    • 如果移出的高位都是1,我们是不能使用上面的计算公式的。
>>:右移,按位右移

说明:原操作数所有二进制位数想右移整体移动指定位,移出的数据舍弃(高补低舍)。

如果操作数是无符号数;左边用0补齐

如果操作数是有符号数:左边用是,什么不全,取决于计算机系统

  • 逻辑右移:用0补全
  • 逻辑左移:用1补全

大部分情况下,系统遵循“算术右移

无符号右移:

语法:

操作数 >> 移动位数

举例:

unsigned char a = 3 >> 3;//0

演示:

在这里插入图片描述

有符号右移:

语法:

操作数 >> 移动位数

演示:

char a = -3 >> 3;// -1

演示:

关于移位运算过程:

原数据→二进制原码→二进制反码→位移运算→二进制反码→二进制原码→特定进制数据

术右移==”

无符号右移:

语法:

操作数 >> 移动位数

举例:

unsigned char a = 3 >> 3;//0

演示:

在这里插入图片描述

有符号右移:

语法:

操作数 >> 移动位数

演示:

char a = -3 >> 3;// -1

演示:

在这里插入图片描述

关于移位运算过程:

原数据→二进制原码→二进制反码→位移运算→二进制反码→二进制原码→特定进制数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值