操作符优先级

算数操作符
有加+、减-、乘*、除/、求余%五种算数操作符。
【注意】
%操作符的两个操作数必须为整数,返回的是整除之后的余数。
对于/操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法。
例如:10/3=3,10/3.0=3.333333,10.0/3=3.333333
移位操作符
移位操作符有两个,分别是:左移操作符和右移操作符。
左移操作符(<<)
左边抛弃,右边补0。
int main()
{
    int a = 1;                  //定义一个整型变量a并赋初值为1
    a = a << 1;                 //将变量a左移一位
    printf("%d",a);         //输出2
    return 0;
}移位运算符会首先将值转换为二进制,例如上面代码中,1的补码为0000 0000 0000 0000 0000 0000 0000 0001,左移一位,就会变成0000 0000 0000 0000 0000 0000 0000 0010,再转换为十进制就是2。
右移操作符(>>)
右边丢弃,左边补原符号位(正数补0,负数补1)
int main()
{
    int a = -4;
    a = a >> 1;                 //右移1位
    printf("%d",a);         //输出-2
    return 0;
}【拓展】
负数的反码 = 原码符号位不变,其他数值位取反。
负数的补码 = 反码 + 1
正数的原码、反码、补码相同
-4的二进制原码为 1000 0000 0000 0000 0000 0000 0000 0100
-4的二进制反码为 1111 1111 1111 1111 1111 1111 1111 1011
-4的二进制补码为 1111 1111 1111 1111 1111 1111 1111 1100
右移一位后为:1111 1111 1111 1111 1111 1111 1111 1110(即-2的补码)
位操作符
& 按位与:有0为0。
| 按位或:有1为0。
^ 按位异或:相同为0,不同为1。
【注意】位操作符的操作数必须都是整数。
按位与(&)
int main()
{
    int x = 5;          //0000 0000 0000 0000 0000 0000 0000 0101
    int y = 7;          //0000 0000 0000 0000 0000 0000 0000 0111
    int num = x & y;    //0000 0000 0000 0000 0000 0000 0000 0101
    printf("%d",num);   //输出5
    return 0;
}按位或(|)
int main()
{
    int x = 5;          //0000 0000 0000 0000 0000 0000 0000 0101
    int y = 7;          //0000 0000 0000 0000 0000 0000 0000 0111
    int num = x | y;    //0000 0000 0000 0000 0000 0000 0000 0111
    printf("%d",num);   //输出7
    return 0;
}按位异或(^)
int main()
{
    int x = 5;          //0000 0000 0000 0000 0000 0000 0000 0101
    int y = 7;          //0000 0000 0000 0000 0000 0000 0000 0111
    int num = x ^ y;    //0000 0000 0000 0000 0000 0000 0000 0010
    printf("%d",num);   //输出2
    return 0;
}赋值操作符
=    +=    -=    *=    /=     %=    <<=    >>=    &=    |=    ^=
【注意】运算符和等号之间是不能有空格的。

int a = 10;     //将后面的值赋予给前面的变量。
    a += 1;         //等同于(a = a + 1)
    a -= 1;         //等同于(a = a - 1)
    a *= 1;         //等同于(a = a * 1)
    a /= 1;         //等同于(a = a / 1)
    a %= 2;         //等同于(a = a % 2)
    a <<= 2;        //等同于(a = a << 2),即a左移2位
    a >>= 2;        //等同于(a = a >> 2),即a右移2位
    a &= 2;         //等同于(a = a & 2),即变量a的值和2按位与。
    a |= 2;         //等同于(a = a | 2),即变量a的值和2按位或。
    a ^= 2;         //等同于(a = a ^ 2),即变量a的值和2按位异或。单目操作符
只有一个操作数的操作符就被成为单目操作符
!    -    +    &    sizeof    ~    --    ++    *    (类型)

逻辑反操作(!)
加上!与之形成相反的逻辑。例如=,加上!变为不等于!=。

对于整型变量,只要不为0,使用!取反后均为1,0取反后为1。(等同于bool类型只有真和假一样,在进行判断时,非0为真,0为假)
负值(-)
正值(+)
取地址(&)
scanf()函数输入时就用到&符号帮我们找到变量的地址,然后在变量地址的内存中存储数据。
int main()
{
    int x;
    scanf("%d",&x);
    return 0;
}sizeof
sizeof可以计算操作数的类型长度(以字节为长度)。
【注意】不是计算操作数本身长度,而是操作数的类型长度。
int main()
{
    int x;
    printf("%d", sizeof(x));
    return 0;
}位取反(~)
对于整型变量,转换为二进制,对每一位二进制取反,0变1,1变0。
int main()
{
    int i = 1;
    printf("%d",~i);    //输出-2
    
    //0000 0000 0000 0000 0000 0000 0000 0001      1的补码
    //1111 1111 1111 1111 1111 1111 1111 1110      ~1(使1的补码,0变1,1变0)的值,补码形式
    //1111 1111 1111 1111 1111 1111 1111 1101      反码(负数的反码 = 补码 - 1)
    //1000 0000 0000 0000 0000 0000 0000 0010      原码(负数的原码 = 反码除符号位0变1,1变0),即为-2
    
    return 0;
}++和--
前置++和--
++i
int main()
{
    int i = 10;
    printf("%d",++i);       //输出11
    /*
     * ++i
     *      先对i自增,然后使用i
     * 可以分解为两步
     *      i = i + 1;
     *      printf("%d",i);         //此时i为11
     */
    return 0;
}--i
int main()
{
    int i = 10;
    printf("%d",--i);       //输出9
    /*
     * --i
     *      先对i自减,然后使用i
     * 可以分解为两步
     *      i = i - 1;
     *      printf("%d",i);         //此时i为9
     */
    return 0;
}后置++和--
i++
int main()
{
    int i = 10;
    printf("%d",i++);       //输出10
    /*
     * i++
     *      先使用i,再i自增
     * 可以分解为两步
     *      printf("%d",i);         //此时i为10
     *      i = i + 1;
     */
    return 0;
}i--
int main()
{
    int i = 10;
    printf("%d",i--);       //输出10
    /*
     * i--
     *      先使用i,再i自减
     * 可以分解为两步
     *      printf("%d",i);         //此时i为10
     *      i = i - 1;
     */
    return 0;
}间接访问操作符(*)
后续指针章节会讲。
强制转换
强制转换类型,将float转换为int
int main()
{
    int a = (int)3.14;      //将浮点数3.14转换为整型3赋值给整型
    printf("%d",a);
    return 0;
}关系操作符
大于>、大于等于>=、小于<、小于等于<=、不相等!=、相等==
关系操作符都是用来判断的。
逻辑操作符

逻辑与(&&)
/*
* 如果年龄大于等于18岁,小于等于24岁即可以不用认证享受大学生受惠
*/
int main()
{
    int age;
    scanf("%d",&age);
    if(age >= 18 && age <= 24){     //如果年龄大于等于18岁并且年龄小于等于24岁
        printf("您无需大学生认证");
    }else{                      //否则
        printf("您需要先进行大学生认证");
    }
    return 0;
}逻辑或(||)
/*
 * 如果年龄在小于等于12岁,大于等于60岁,进入动物园免费
 */
int main()
{
    int age;
    scanf("%d",&age);
    if(age <= 12 || age >= 60){     //如果年龄小于等于12岁或者年龄大于等于60岁
        printf("无需买票");
    }else{                      //否则
        printf("请先买票");
    }
    return 0;
}条件操作符(三元运算符)
语法:条件表达式1 ? 表达式2 : 表达式3;
先判断条件表达式1是否为真,为真执行表达式2,为假执行表达式3。
int main()
{
    int a = 10,b = 20;
    a > b ? ++a : ++b;
    printf("%d %d",a,b);    //输出10 21
    return 0;
}首先判断a>b为假,执行++b。所以输出a的值为10,b的值为21。
int main()
{
    int a = 10,b = 20,c = 0;
    c = a > b ? ++a : ++b;
    printf("%d",c);    //输出21
    return 0;
}首先判断a>b为假,式子等同于c = ++b;。所以输出c的值为21。
逗号表达式
它将两个及其以上的式子联接起来,从左往右逐个计算表达式,整个表达式的值为最后一个表达式的值。
如:(3+5,6+8)称为逗号表达式,其求解过程先表达式1,后表达式2,整个表达式值是表达式2的值。
int main()
{
    int a = 1,b = 0;
    b = (a = 3,a * 4);
    printf("%d",b);    //输出12
    return 0;
}先将3的值赋值给a,再将a和4相乘,最后赋值给b。输出12。
【注意】以下两个代码结果并不相同
int main()
{
    int x = 1,y = 1,z;
    z = x++,y++,++y;
    printf("%d %d %d",x,y,z);           //输出2 3 1
    return 0;
}
int main()
{
    int x = 1,y = 1,z;
    z = (x++,y++,++y);
    printf("%d %d %d",x,y,z);       //输出2 3 3
    return 0;
}因为逗号表达式优先级最低,所以第一个代码其实上是:(z = x++),y++,++y;
使用逗号表达式时应该特别注意操作符的优先级问题。










