操作符和表达式
操作符
分类:
- 算术操作符
- 移位操作符
- 位操作符
- 赋值操作符
- 单目操作符
- 关系操作符
- 逻辑操作符
- 条件操作符
- 逗号表达式
- 下标引用、函数调用和结构成员访问的相关操作符
算术操作符
+ - * / %
算术操作符的使用:
注:直接写出的小数,编译器会默认认为是double类型的数
注:%和/是不支持被零除或被零求模的
总结:
- 除了 % 操作符之外,其他的几个操作符可以作用于整数和浮点数。
- 对于 / 操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法。
- % 操作符的两个操作数必须为整数。返回的是整除之后的余数。
移位操作符
<< 左移操作符
>> 右移操作符
左移操作符 移位规则:左边抛弃、右边补0
注:左移操作符左边抛弃、右边补0(包括符号位,移动到符号位是什么就是什么)
右移操作符 移位规则:
首先右移运算分两种:
- 逻辑移位 左边用0填充,右边丢弃
- 算术移位 左边用原该值的符号位填充,右边丢弃
可以看出在VS编译器下采用的是算术右移
注意:
- 右移操作符分为逻辑右移、算术右移,通常采用的是算术右移
- 对于移位运算符,不要移动负数位,这个是标准未定义的。
例如:
int num = 10;
num>>-1;//error
补充:
- 负整数在内存中是以二进制补码的形式存储的
- 整数的二进制表示形式有3种:原码、反码、补码
- 针对负整数二进制的表示形式:
-
- 原码:直接根据数值写出的二进制序列就是原码
-
- 反码:原码的符号位不变,其他位按按取反就是反码
-
- 补码:反码+1,就是补码
- 对于正整数来说原码、反码、补码是相同的
位操作符
& //按位与
| //按位或
^ //按位异或
按位与操作符的使用:
按位或操作符的使用:
按位异或操作符的使用:
注:
- 他们的操作数必须是整数。
- 任何两个相同的数异或一定是0;0与任何一个数异或还是它本身
- 这些操作符运算时符号位也会计算进去
练习:
不能创建临时变量(第三个变量),实现两个数的交换。
//版本一:
int main()
{
int a = 3;
int b = 5;
printf("a = %d b = %d\n", a, b);
//数值太大会溢出
a = a + b;
b = a - b;
a = a - b;
printf("a = %d b = %d\n", a, b);
return 0;
}
//版本二:
int main()
{
int a = 3;
int b = 5;
//交换
printf("a=%d b=%d\n", a, b);
a = a ^ b;
b = a ^ b;
a = a ^ b;
printf("a=%d b=%d\n", a, b);
return 0;
}
版本一是有缺陷的,当两个数值过大时两数相加会发生溢出现象(因为int存储是存在范围的,如果过大会发生溢出)。但是版本二就不存在这种现象,因为没有进位就不存在溢出。
编写代码实现:求一个整数存储在内存中的二进制中1的个数。
#include <stdio.h>
int main()
{
int num = -1;
int i = 0;
int count = 0;//计数
while(num)
{
count++;
num = num&(num-1);
}
printf("二进制中1的个数 = %d\n",count);
return 0;
}
赋值操作符
赋值操作符的使用:
double salary = 10000.0;
salary = 20000.0;//使用赋值操作符赋值。
//赋值操作符可以连续使用
int a = 10;
int x = 0;
int y = 20;
a = x = y+1;//连续赋值
//与上面的代码含义相同
x = y+1;
a = x;
//这样的写法更加清晰爽朗而且易于调试。
复合赋值符
+=
-=
*=
/=
%=
>>=
<<=
&=
|=
^=
这些运算符都可以写成复合的效果
复合赋值符的使用:
int x = 10;
x = x+10;
x += 10;//复合赋值
//上面两行代码是等价的
//其他运算符一样的道理。这样写更加简洁。
注意:在C语言中=赋值;==判断是否相等
单目操作符
单目操作符是只有一个操作数的操作符
! 逻辑反操作
- 负值
+ 正值
& 取地址
sizeof 操作数的类型长度(以字节为单位)
~ 对一个数的二进制按位取反
-- 前置、后置--
++ 前置、后置++
* 间接访问操作符(解引用操作符)
(类型) 强制类型转换
逻辑反操作符的使用:
int main()
{
int flag = 5;
printf("%d\n", !flag);//0
int u = 0;
printf("%d\n", !u); //1
//flag为真,打印hehe
if (flag)
{
printf("hehe\n");
}
//flag为假,打印haha
if