+ - * / %
1. 除了 % 操作符之外,其他的几个操作符可以作用于整数和浮点数。% 操作符的两个操作数必须为整数,返回的是整除之后的余数
2. 对于 / 操作符如果两个操作数都为整数,执行整数除法,而只要有浮点数执行的就是浮点数除法。也就是说,如果想要得到小数,除数和被除数之间至少有一个数是浮点数
int main()
{
int a = 6/5;
printf("%d ", a);
float b = 6 / 5;
printf("%f ", b);
float c = 6 / 5.0;
printf("%f ", c);
return 0;
}
输出:1 1.000000 1.200000
二、移位操作符<< 左移操作符
>> 右移操作符
1.左移操作符
移位规则:左边抛弃、右边补0
2.右移操作符
移位规则:
① 算术移位
左边用原该值的符号位填充,右边丢弃(负数符号位为1,正数符号位为0)
② 逻辑移位
左边用0填充,右边丢弃
一个整数的二进制表示有三种:原码、反码、补码
-1的二进制表示(以下方法针对负整数,正整数的原码、反码、补码相同):
原码:10000000000000000000000000000001(第一位为符号位)
反码:11111111111111111111111111111110(符号位不变,原码其他位按位取反)
补码:11111111111111111111111111111111(符号位不变,反码+1)
负整数内存中存储的是补码
int main()
{
int a = -1;
int b = a >> 1;
printf("a=%d ", a);
printf("b=%d", b);
return 0;
}
输出:a=-1 b=-1
VS2019右移操作符使用的是算数右移,且a右移一位并不会改变a的值
:对于移位运算符,不要移动负数位,这个是标准未定义的且没有意义
3.位操作符& 按位与
| 按位
^ 按位异或
位操作符的操作数必须是整数
按位指按二进制位
int main()
{
int a = 3; //00000000000000000000000000000011
int b = 5 ;//00000000000000000000000000000101
int c = a & b;//00000000000000000000000000000001
int d = a | b;//00000000000000000000000000000111
int e = a ^ b;//00000000000000000000000000000110
printf("a&b=%d ", c);
printf("a|b=%d ", d);
printf("a^b=%d ", e);
return 0;
}
输出:1 7 6
练习1:不能创建临时变量(第三个变量),实现两个数的交换
法一:加减(存在缺点:数字过大时可能溢出)
int main()
{
int a = 3;
int b = 5;
a = a + b;
b = a - b;
a = a - b;
printf("a=%dn", a);
printf("b=%d", b);
return 0;
}
法二:异或
int main()
{
int a = 3;//a:011
int b = 5;//b:101
a = a ^ b;//a:110
b = a ^ b;//b:011--原来的a
a = a ^ b;//a:101--原来的b
printf("a=%dn", a);
printf("b=%d", b);
return 0;
}
练习2:求一个整数存储在内存中的二进制中1的个数
法1:缺点是不能计算负数
int main()
{
int num = 10;
int count = 0;
while (num)
{
if (num % 2 == 1)
count++;
num = num / 2;
}
printf("%d二进制中1的个数%为%dn", num, count);
return 0;
}
法2:缺点是需要循环32次
int main()
{
int num = 10;//00000000000000000000000000010010
int i = 0;
int count = 0;//计数
for (i = 0; i < 32; i++)
{
if ((num >>i)&1==1)
count++;
}
printf("%d二进制中1的个数%为%dn", num,count);
return 0;
}
法3:
int main()
{
int num = 10;
int count = 0;
while (num)
{
count++;
num = num & num - 1;
}
printf("%d二进制中1的个数为:%dn", num, count);
return 0;
}
例:
num=10010 num-1=10001
num=10000 num-1=01111
num=00000
4.赋值操作符直接赋值:=
复合赋值:+= -= *= /= %= >>= <<= &= |= ^=
一个 = 是赋值,两个 = 是判断相等
5.单目操作符! 逻辑反操作 - 负值 + 正值 & 取地址 sizeof 操作数的类型长度(以字节为单位) ~ 对一个数的二进制按位取反 -- 前置、后置 -- ++ 前置、后置 ++ * 间接访问操作符 ( 解引用操作符 ) ( 类型 ) 强制类型转换
①用sizeof计算数组大小时,可以不加括号,但是计算变量类型的大小时,必须加括号
int main()
{
char arr[10] = { 0 };
printf("%dn", sizeof(arr));
printf("%dn", sizeof(int));
printf("%dn", sizeof arr);
printf("%dn", sizeof int);
return 0;
}
输出:10 4 10
因此,sizeof是一个操作符,并不是函数
②以下两种方式均可以计算数组的大小
int main()
{
int arr[10] = { 0 };
printf("%dn", sizeof(arr));
printf("%dn", sizeof(int[10]));
return 0;
}
③
int main()
{
short s = 5;
int a = 10;
printf("%dn", sizeof(s = a + 2));
printf("%dn", s);
return 0;
}
输出:2 5
这是因为电脑是在编译器阶段处理sizeof的,sizeof括号里的表达式是不参与运算的,s=a+2在编译器阶段已经处理过,在运行期间并不会计算s=a+2
④前置/后置++与--
后置++:先使用,再++
int main()
{
int a = 10;
int b = a++;
printf("%d ", a);
printf("%d ", b);
return 0;
}
输出:11 10
前置++:先++,再使用
int main()
{
int a = 10;
int b = ++a;
printf("%d ", a);
printf("%d ", b);
return 0;
}
输出:11 11
int main()
{
int a = 10;
printf("%d ", a--);
printf("%d ", a);
return 0;
}
输出:10 9
6.关系操作符> >= < <= != 用于测试 “ 不相等 ” == 用于测试 “ 相等 ”7.逻辑操作符
&& 逻辑与 || 逻辑或8.条件操作符
exp1 ? exp2 : exp39.逗号表达式
exp1 , exp2 , exp3 , …expN10.下标引用、函数调用和结构成员
10.1. [ ] 下标引用操作符
操作数:一个数组名 + 一个索引值10.2 ( ) 函数调用操作符
接受一个或者多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数。10.3 访问一个结构的成员
. 结构体 . 成员名 -> 结构体指针 -> 成员名11.表达式求值 11.1 隐式类型转换 11.2 算术转换 12.3 操作符的属性



