运算符(C语言)

一、算术运算

1、*、/

+-,CPU在一个周期内可以处理完。

*/在大多数CPU中都是不支持的。
它们可能需要CPU多个周期才能完成,甚至要利用软件的模拟方法去实现。

在arm开发中,*/很可能会被编译器编辑为软件浮点方法。如果是裸机开发,就实现不了,必须借助第三方乘法库/除法库来实现。

如果CPU不支持*/,会导致程序的可移植性变差。

2、%

0%3 = 0   
1%3 = 1 
2%3 = 2  
3%3 = 0  
4%3 = 1 
... ...

应用场景:

  • 取一个范围的数
    例如:给一个任意的数字m,得到一个1到100以内的数字?

    (m % 100)+1 
    
  • M进制的数

  • 循环数据结构的下标


二、逻辑运算

1、&&、||

// 001.c
#include 
int main()
{
    int a = 10;
    int res = 0;
    res = ((a == 10) || printf("======\n"));
    printf("res is %d\n", res);
    return 0;
}
运算符(C语言)_第1张图片
|| 左边的值为真,则不判断右边的值
// 002.c
#include 
int main()
{
    int a = 10;
    int res = 0;
    res = ((a != 10) || printf("======\n"));
    printf("res is %d\n", res);
    return 0;
}
运算符(C语言)_第2张图片
|| 左边的值为假时,才判断右边的值

2、!

逻辑运算的!和位运算的~区别

int a = 0x0;
!a : 真
~a :0xffff

三、位运算

C语言中最接近底层和硬件开发的一种运算。
对嵌入式工程师,应用频率非常高。

1、移位:<<(左移)、>>(右移)

<<(左移):左移1位,相当于2*
m<

4 ——  0100
8 ——  1000

int a = b*32 ——> int a = b<<5   // C语言会将b*32转化为b<<5,这样CPU在一个周期内就可以处理完了

-1 * 2 = -2
8bit举例:
-1:
原码:1 0 0 0 0 0 0 1
反码:1 1 1 1 1 1 1 0
补码:1 1 1 1 1 1 1 1    // -1在计算机中全是高电平

-2:
原码:1 0 0 0 0 0 1 0
反码:1 1 1 1 1 1 0 1
补码:1 1 1 1 1 1 1 0
// -1左移1位,最后面一位就空了,就用0补位。
// 可看出,-2是-1左移一位得到的

>>(右移):右移1位,相当于/2
m>>n :m/2^n

// 右移与正负符号有关
int a;  a>>n
unsigned int a;  a>>n
// 这两种情况CPU表现形式是不一样的

右移时,如果是负数,则最左边补1; 如果是正数,最左边补0。

/*003.c*/
#include 
int main()
{
    int a = 10;
    while(a) 
    {
        a = a>>1;   // 当a全0时,就不再循环
    }
    printf("++++++++++\n");
}
运算符(C语言)_第3张图片
/*004.c*/
#include 
int main()
{
    int a = -10;
    while(a) 
    {
        a = a>>1;   // 因为a为负数,首位永远是1,因此a永远无法为0,该循环为死循环
    }
    printf("++++++++++\n");
}

2、&(逐位与)、|(逐位或)

(1)&的应用场景:

  • 屏蔽

    A & 0 —— 0 
    int a = 0x1234;
    a & 0xff00;    // 屏蔽低8位(bit),取出了高8bit
    

硬件中,&也叫清零器(clear)

  • 取出

    A & 1 —— A
    

(2)|的应用场景:

  • 设置为高电平

    A | 1 —— 1
    

硬件中,|也叫设置器(set)

  • 保留

    A | 0 —— A
    

例1:设置一个资源的bit5为高电平,其它位不变。

int a;
a = a | 100000   // 末尾一位是bit0,倒数第2位为bit1 ...

a = a | (0x1<<5)

a | (0x1<

例2:清除第5位。

int a;

a = a & 0 1 1 1 1 1   // 这个写法是错误的,因为高位为0,会把a的高位也同时都清零;而且,如果移植到别的平台,前面的0更多的话,把把更多位清零。

a = a & (~(0x1<<5))   // 只有第5位为0,其它位全为1

a & (~(0x1<

例3:某几位设置为某个数。
如,想设置4、5、6bit为101,该怎么处理?

3、^(异或)

1 ^ 1 = 0
0 ^ 0 = 0
1 ^ 0 = 1

硬件上用的不多,主要用在算法上。在设计的数学算法上,会用到^进行加密、解密(AES、SHA1等)。

例:两数交换。

int a = 20;
int b = 30;

// 方法1:引入中间变量。
int c;
c = a;
a = b;
b =c;

// 方法2:不引入中间变量。
a = a ^ b;
b = a ^ b;
a = a ^ b;

4、~(逐位取反)

~0xf0 (32位常量):  0xffff ff0f

四、内存访问符号

对于连续空间中不同成员变量的访问方法:
->:地址访问。
.:变量访问。

&p:取地址。
*p:指针。


五、逻辑结构

switch里面必须用整型数字,不能用浮点数。

内核编程中,有的场景不得不用goto。
一定要保证goto不能在不同函数间跳,在同一函数内是没有问题的。

你可能感兴趣的:(运算符(C语言))