从零开始学嵌入式技术之C语言06:运算符基础

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

        表达式指的是一组运算数、运算符的组合,表达式一定具有值,一个变量或一个常量就是一个表达式,变量、常量与运算符也可以组成复杂一些的表达式。

一:运算符分类

(1)按照操作数个数分类:

  • 一元运算符(一目运算符)
  • 二元运算符(二目运算符)
  • 三元运算符(三目运算符)

(2) 按照功能分类:

  • 算术运算符
  • 赋值运算符
  • 关系运算符
  • 逻辑运算符
  • 位运算符

 二:算术运算符

        算术运算符是对数值类型的变量进行运算的,在C程序中使用的非常多。

运算符

描述

操作数个数

组成的表达式的值

副作用

+

正号

1

操作数本身

-

负号

1

操作数符号取反

+

加号

2

两个操作数之和

-

减号

2

两个操作数之差

*

乘号

2

两个操作数之积

/

除号

2

两个操作数之商

%

取模(取余)

2

两个操作数相除的余数

++

自增

1

操作数自增前或自增后的值

- -

自减

1

操作数自减前或自减后的值

//正号和负号
#include <stdio.h>

int main()
{
    int x = 12;
    int x1 = -x, x2 = +x;

    int y = -67;
    int y1 = -y, y2 = +y;

    printf("x1=%d, x2=%d \n", x1, x2);
    printf("y1=%d, y2=%d \n", y1, y2);

    return 0;
}
//加、减、乘、除
#include <stdio.h>

int main()
{
    int a = 5 + 2.5;
    printf("%d\n", a * a);

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

    double c = 6.0 / 4;
    printf("%f\n", c); // 输出 1.500000

    return 0;
}

 注意:整数之间做除法时,结果只保留整数部分而舍弃小数部分。

//取模(取余)
#include <stdio.h>

int main()
{
    int res1 = 10 % 3;
    printf("%d\n", res1);

    int res2 = -10 % 3;
    printf("%d\n", res2);

    int res3 = 10 % -3;
    printf("%d\n", res3);

    int res4 = -10 % -3;
    printf("%d\n", res4);

    return 0;
}

 注意运算结果的符号与被模数也就是第一个操作数相同。

自增和自减

  1. 自增、自减运算符可以写在操作数的前面也可以写在操作数后面,不论前面还是后面,对操作数的副作用是一致的。 
  2. 自增、自减运算符在前在后,对于表达式的值是不同的。 如果运算符在前,表达式的值是操作数自增、自减之后的值;如果运算符在后,表达式的值是操作数自增、自减之前的值。
//自增和自减
#include <stdio.h>

int main()
{
    int i1 = 10, i2 = 20;
    int i = i1++;
    printf("%d\n", i);  // 10
    printf("%d\n", i1); // 11

    i = ++i1;
    printf("%d\n", i);  // 12
    printf("%d\n", i1); // 12

    i = i2--;
    printf("%d\n", i);  // 20
    printf("%d\n", i2); // 19

    i = --i2;
    printf("%d\n", i);  // 18
    printf("%d\n", i2); // 18

    return 0;
}

三:关系运算符(比较运算符)

运算符

描述

操作数个数

表达式的值

副作用

==

相等

2

0 或 1

!=

不等

2

0 或 1

<

小于

2

0 或 1

>

大于

2

0 或 1

<=

小于等于

2

0 或 1

>=

大于等于

2

0 或 1

#include <stdio.h>

int main() 
{
    int a = 8;
    int b = 7;

    printf("a>b的值:%d \n", a > b); 
    printf("a>=b的值:%d \n", a >= b); 
    printf("a<b的值:%d \n", a < b); 
    printf("a<=b的值:%d \n", a <= b);
    printf("a==b的值:%d \n", a == b);
    printf("a!=b的值:%d \n", a != b);

    return 0;;
}

 四:逻辑运算符

运算符

描述

操作数个数

表达式的值

副作用

&&

逻辑与

2

0 或 1

||

逻辑或

2

0 或 1

!

逻辑非

1

0 或 1

 (1):逻辑与 &&

        如果两个操作数都为真(非零),那么表达式的值为真,否则为假。

        如果第一个操作数为假,第二个操作数没有计算的必要了,这种现象称为短路现象。

#include <stdio.h>

int main()
{
    double score = 70; // 成绩

    if (score >= 60 && score <= 80)
    {
        printf("ok1 \n");
    }
    else
    {
        printf("ok2 \n");
    }

    int a = 10, b = 99;

    // 短路现象
    if (a < 2 && ++b > 99)
    {
        printf("ok100");
    }
    printf("b=%d\n", b);

    return 0;
}

(2):逻辑或 ||

        只要有一个操作数为真,表达式的值就为真;两个操作数都为假,表达式的值为假。

        如果第一个操作数为真,第二个操作数没有计算的必要了,这种现象称为短路现象。

#include <stdio.h>

int main()
{
    double score = 70;

    if (score >= 70 || score <= 80)
    {
        printf("ok1 \n");
    }
    else
    {
        printf("ok2 \n");
    }

    int a = 10, b = 99;

    // 短路现象
    if (a > 5 || b++ > 100)
    { //
        printf("ok100 \n");
    }
    printf("b=%d\n", b);

    return 0;
}

 (3):逻辑非

        操作数状态取反作为表达式的值。

#include <stdio.h>

int main()
{
    int score = 100;
    int res = score > 99;

    if (res)
    {
        printf("hello, tom \n");
    }
    if (!res)
    { 
        printf("hello,jack \n");
    }

    return 0;
}

五:赋值运算符

运算符

描述

操作数个数

表达式的值

副作用

=

赋值

2

左边操作数的值

+=

相加赋值

2

左边操作数的值

-=

相减赋值

2

左边操作数的值

*=

相乘赋值

2

左边操作数的值

/=

相除赋值

2

左边操作数的值

%=

取余赋值

2

左边操作数的值

<<=

左移赋值

2

左边操作数的值

>>=

右移赋值

2

左边操作数的值

&=

按位与赋值

2

左边操作数的值

^=

按位异或赋值

2

左边操作数的值

|=

按位或赋值

2

左边操作数的值

  1. 赋值运算符的第一个操作数(左值)必须是变量的形式,第二个操作数可以是任何形式的表达式。
  2. 赋值运算符的副作用针对第一个操作数。
#include <stdio.h>

int main()
{
    int a = 10, b = 20, c = 30;

    c += 3;   // 等价于 c = c + 3;   计算后c的值变为33
    c += b;   // 等价于 c = c + b;   计算后c的值变为53
    a += 1.7; // 等价于 a = a + 1.7  计算后a的值变为11

    printf("a=%d b=%d c=%d", a, b, c);

    return 0;
}

 六:位运算符

运算符

描述

操作数个数

副作用

&

按位与

2

|

按位或

2

^

按位异或

2

~

按位取反

1

<<

按位左移

2

>>

按位右移

2

注意:操作数进行位运算的时候,以它的补码形式进行运算。

(1):按位与、按位或、按位异或 

#include <stdio.h>

int main()
{
    int a = 17;
    int b = -12;

    printf("a&b=%d\n", a & b); // a&b=16
    printf("a|b=%d\n", a | b); // a|b=-11
    printf("a^b=%d\n", a ^ b); // a^b=-27

    return 0;
}

(2):按位取反

#include <stdio.h>

int main()
{
    int a = 17;
    int b = -12;

    // 按位非
    printf("~a=%d\n", ~a); 
    printf("~b=%d\n", ~b); 

    return 0;
}

(3):按位左移、按位右移

#include <stdio.h>

int main()
{
    int a = 17;
    int b = -12;

    // 按位左移
    printf("a<<2=%d\n", a << 2); // a<<2=68
    printf("b<<2=%d\n", b << 2); // b<<2=-48

    // 按位右移
    printf("a>>3=%d\n", a >> 3); // a>>3=2
    printf("b>>3=%d\n", b >> 3); // b>>3=-2

    return 0;
}

七:​​​​​​​三元运算符

基本语法:

        条件表达式? 表达式1: 表达式2;

        如果条件表达式为非0(真),整个表达式的值是表达式1;

        如果条件表达式为0(假),整个表达式的值是表达式2;

#include <stdio.h>

int main()
{
    int a = 10;
    int b = 99;
    int res = a > b ? a++ : b--;
    int n1 = a > b ? 1.1 : 1.2;

    printf("a=%d \n", a);
    printf("b=%d \n", b);
    printf("res=%d \n", res);

    return 0;
}
  1. 计算两个数的最大值a , b
#include <stdio.h>

int main()
{
    int a = 10;
    int b = 100;

    int max = a > b ? a : b;

    printf("a和b中最大的数字:%d", max);

    return 0;
}

 2.计算三个数的最大值

#include <stdio.h>

int main()
{
    int a = 10;
    int b = 100;
    int c = 199;

    // int max1 = a>b ? a : b;
    // int max2 = max1>c ? max1:c;
    int max = (a > b ? a : b) > c ? (a > b ? a : b) : c;

    printf("a、b、c中最大的数字:%d", max);

    return 0;
}

 八:​​​​​​​运算符优先级

优先级

运算符

名称或含义

结合方向

1

[]

数组下标

左到右

()

圆括号

.

成员选择(对象)

->

成员选择(指针)

2

-

负号运算符

右到左

(类型)

强制类型转换

++

自增运算符

--

自减运算符

*

取值运算符

&

取地址运算符

!

逻辑非运算符

~

按位取反运算符

sizeof

长度运算符

3

/

左到右

*

%

余数(取模)

4

+

左到右

-

5

<<

左移

左到右

>>

右移

6

>

大于

左到右

>=

大于等于

<

小于

<=

小于等于

7

==

等于

左到右

!=

不等于

8

&

按位与

左到右

9

^

按位异或

左到右

10

|

按位或

左到右

11

&&

逻辑与

左到右

12

||

逻辑或

左到右

13

?:

条件运算符

右到左

14

=

赋值运算符

右到左

/=

除后赋值

*=

乘后赋值

%=

取模后赋值

+=

加后赋值

-=

减后赋值

<<=

左移后赋值

>>=

右移后赋值

&=

按位与后赋值

^=

按位异或后赋值

|=

按位或后赋值

15

,

逗号运算符

左到右

总结:

  1. 不要过多的依赖运算的优先级来控制表达式的执行顺序,这样可读性太差,尽量使用小括号来控制表达式的执行顺序。
  2. 不要把一个表达式写得过于复杂,如果一个表达式过于复杂,则把它分成几步来完成。
  3. 运算符优先级不用刻意地去记忆,总体上:一元运算符 > 算术运算符 > 关系运算符 > 逻辑运算符 > 三元运算符 > 赋值运算符。

        本章的内容就到这里。

        关注我一起成为嵌入式大佬。

 

【轴承故障诊断】加权多尺度字典习模型(WMSDL)及其在轴承故障诊断上的应用(Matlab代码实现)内容概要:本文介绍了加权多尺度字典习模型(WMSDL)在轴承故障诊断中的应用,并提供了基于Matlab的代码实现。该模型结合多尺度分析与字典技术,能够有效提取轴承振动信号中的故障特征,提升故障识别精度。文档重点阐述了WMSDL模型的理论基础、算法流程及其在实际故障诊断中的实施步骤,展示了其相较于传统方法在特征表达能力和诊断准确性方面的优势。同时,文中还提及该资源属于一个涵盖多个科研方向的技术合集,包括智能优化算法、机器习、信号处理、电力系统等多个领域的Matlab仿真案例。; 适合人群:具备一定信号处理和机器基础,从事机械故障诊断、工业自动化、智能制造等相关领域的研究生、科研人员及工程技术人员。; 使用场景及目标:①习并掌握加权多尺度字典习模型的基本原理与实现方法;②将其应用于旋转机械的轴承故障特征提取与智能诊断;③结合实际工程数据复现算法,提升故障诊断系统的准确性和鲁棒性。; 阅读建议:建议读者结合提供的Matlab代码进行实践操作,重点关注字典习的训练过程与多尺度分解的实现细节,同时可参考文中提到的其他相关技术(如VMD、CNN、BILSTM等)进行对比实验与算法优化。
【硕士论文复现】可再生能源发电与电动汽车的协同调度策略研究(Matlab代码实现)内容概要:本文档围绕“可再生能源发电与电动汽车的协同调度策略研究”展开,旨在通过Matlab代码复现硕士论文中的核心模型与算法,探讨可再生能源(如风电、光伏)与大规模电动汽车接入电网后的协同优化调度方法。研究重点包括考虑需求侧响应的多时间尺度调度、电动汽车集群有序充电优化、源荷不确定性建模及鲁棒优化方法的应用。文中提供了完整的Matlab实现代码与仿真模型,涵盖从场景生成、数建模到求解算法(如NSGA-III、粒子群优化、ADMM等)的全过程,帮助读者深入理解微电网与智能电网中的能量管理机制。; 适合人群:具备一定电力系统基础知识和Matlab编程能力的研究生、科研人员及从事新能源、智能电网、电动汽车等领域技术研发的工程人员。; 使用场景及目标:①用于复现和验证硕士论文中的协同调度模型;②支撑科研工作中关于可再生能源消纳、电动汽车V2G调度、需求响应机制等课题的算法开发与仿真验证;③作为教案例辅助讲授能源互联网中的优化调度理论与实践。; 阅读建议:建议结合文档提供的网盘资源下载完整代码,按照目录顺序逐步习各模块实现,重点关注模型构建逻辑与优化算法的Matlab实现细节,并通过修改参数进行仿真实验以加深理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值