操作符和表达式(C语言)

操作符和表达式

算术操作符(常用)

    +    -    *    /    %

注意:
1. + — * /均可以作用于整数和浮点数。
2. 对于/操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法。
3. %操作符的两个操作数必须为整数。返回的是整除之后的余数。

移位操作符

左移运算符(<<)

规则:
  按二进制形式把所有的数字向左移动对应的位数,高位移出(舍弃),低位的空位补零。

例: 3 << 2
计算过程:
这里写图片描述

数学意义:
        在数字没有溢出的前提下,对于正数和负数,左移一位都相当于乘以2的1次方,左移n位就相当于乘以2的n次方。

右移运算符(>>)

规则:
        按二进制形式把所有的数字向右移动对应位移位数,低位移出(舍弃),高位的空位补符号位,即正数补零,负数补1。

例1:11 >> 2
计算过程:
这里写图片描述

例2:-7 >> 2
计算过程:
这里写图片描述

数学意义:
右移一位相当于除2,右移n位相当于除以2的n次方。

注意:移位操作符不能移动负数位

位操作符

& :按位与(相同位置只有都为1才为1)
| :按位或(相同位置要有一个位为1就为1)
^ :按位异或(相同位置相同为0,不同则为1)
注意:他们的操作数都必须是整数,按位故而需要按照整数的二进制每位操作,

应用

1.求一个整数二进制中1的个数?

//方法一
int CountOfNum1(int num)
{
    int count = 0;
    while (num > 0)
    {
        if (num % 2 == 1)
            count++;
        num = num / 2;
    }
    return count;
}
//方法二
int CountOfNum2(int num)
{
    int count = 0;
    int i = 0;
    for (i = 0; i < 32; ++i)
    {
       //把每一位右移到最右边和1按位与,统计1出现的次数
        if (((num >> i)&1) == 1)
        {
            count++;
        }
    }
    return count;
}
//方法三(最优)
int CountOfNum3(int num)
{
    int count = 0;
    while (num)
    {
        count++;
        num = num&(num - 1);
    }
    return count;
}

2.不能创建临时变量(第三个变量),实现两个数的交换

int main()
{
    int a = 10;
    int b = 20;
    //利用异或性质中间导了一遍
    a = a^b;
    b = a^b;
    a = a^b;
    printf("a = %d  b = %d\n", a, b);
    system("pause");
    return 0;
}

赋值操作符

简单赋值

赋值操作符比较简单,就是给变量赋值,比较常见的就是我们在对一个已经被赋值的变量进行修改,直接将这个变量直接赋值成你想要的
例如:

int a = 0;
a = 10;

复合赋值

+=         -=         /=         *=         %=         >>=         <<=         &=         |=    等等

单目操作符

操作符 名称
逻辑反操作符
- 负号
+ 正号
& 取地址
自减
++ 自增
~ 按位取反
* 解引用、间接访问
sizeof 类型长度
(类型) 强制类型转换

注意:结合使用时一定要搞清楚优先级,如果不清楚,手动加上括号来控制

关系操作符

符号 名称
> 大于
>= 大于等于
< 小于
<= 小于等于
== 等于等于
!= 不等于
int main()
{
    int a = 3;
    printf("%d", a += a-= a * a);
    return 0;
}

输出结果
-12
做题思路:
由于每次都需要将后面的值算出来才能进行-=和+=,故此题是按照从右向左计算的,为了方便理解,我们可以拆分计算
a += (a -= a*a)    a -= (a*a)     b = a*a=9
a -= (a*a)--> a -= b---> a = -6(注意此时a的值已经是6了,后面运算时a的值都以6计算)
a += (a -= a*a)---> a += a ---> -6+(-6)=-12

逻辑操作符

&& 逻辑与(“并且”):两个操作数都为真,结果才为真
||    逻辑或(“或者”):所有操作数都为假时才为假,有一个或者多个操作数为真就为真

注意:区分逻辑与/或 和 按位与/或的区别

#include <stdio.h>
int main() {
       int i = 0,a=1,b=2,c =3,d=4;
       i = a++&&++b&&d++;
       //i = a++||++b||d++;
       printf("a = %d\n b = %d\n c = %d\nd = %d\n", a, b, c, d);
       return 0;
}

输出结果
    2335
//  2234

条件操作符

A ? B : C — 三元运算符
在某些场景下可以替代if else语句

if(y > 0)
    x = 1;
else
    x = 0;

以上代码等同于下段代码

( y > 0) ? x = 1 : x = 0;

逗号表达式

将两个及以上的式子连接起来,整个表达式的值是最后一个表达式的值

  1. 从左到右依次计算
  2. 最终值是表达式中最后一个表达式的值
  3. 所有运算符中优先级最低的

例:

int main()
{
    int i = 1;
    int j = 1;
    int z = 0;
    z = i++,j++,++j;
    //z = (i++,j++,++j);
    printf("i=%d j=%d z=%d",i,j,z);
    return 0;
}

输出结果
    2,3,1
//  2,3,3
解题思路:
z = i++,j++,++j;因为=的优先级要高于逗号表达式,所以原式等于(z = i++,j++,++j;
因为后置加加先使用后加加,所以z=1,i=2,j++时j为1,当走到j++后面的,时j已经变成2,++j后就成了3。

同理 z = (i++,j++,++j);()的优先级高于=,所以先算()里的逗号表达式,再算=,所以z=3。

某些场景逗号表达式也可以使表达简洁

    //while(a > 0)
    //{
    //    a = test();
    //    a++;
    //}
    //等价上面代码
    while(a = test(), a++, a > 0)

下标引用、函数调用和结构成员

符号 功能
[] 数组访问
() 函数调用
. 结构体/类 访问成员
-> 结构体/类 指针访问成员

猜你喜欢

转载自blog.csdn.net/wsq119/article/details/81229697