1、算术操作
(1)除了了%操作符之外,其他的⼏几个操作符可以作⽤用于整数和浮点数。
(2)对于/操作符如果两个操作数都为整数,执⾏行行整数除法。而只要有浮点数执⾏的就是浮点数
(3)%操作符的两个操作数必须为整数。返回的是整除之后的余数。
2、移位操作符
移位操作符 a<<1;左移1位(对二进制)
右移操作符a>>1;右移1位。
首先右移运算分两种:
(1)逻辑移位
左边用0填充,右边丢弃
(2)算术移位
左边用原该值的符号位填充,右边丢弃
【注意:对于移位运算符,不不要移动负数位,这个是标准未定义的。】
3、暗位操作符
(1)Int a = 10;int b = 20;int c = a&b;
C=0;
二进制 01010
10100
00000
(2)负数,二进制 原码->反码->补码->与
& // 按位与
| // 按位或
^ // 按位异或
注:他们的操作数必须是整数。
例题:算一个数存储在二进制序列中1的个数。
参考代码:
方法 1
#include <stdio.h>
int main()
{
int num = 10;
int count= 0;// 计数
while(num)
{
if(num%2 == 1)
count++;
num = num/2;
}
printf("⼆二进制中1的个数 = %d\n", count);
return 0;
} // 思考这样的实现⽅方式有没有问题?
方法 2 :
#include <stdio.h>
int main()
{
int num = -1;
int i = 0;
int count = 0;// 计数
for(i=0; i<32; i++)
{
if( ((num>>i)&1) == 1 )
count++;
}
printf("⼆二进制中1的个数 =%d\n",count);
return 0;
} // 思考还能不不能更更加优化,这⾥里里必须循环 32 次的。
方法 3 :
#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;
} // 这种⽅方式是不不是很好?达到了了优化的效果,但是难以想到。
【注意:对于移位运算符,不不要移动负数位,这个是标准未定义的。】
例如:
int num = 10; num>>-1;//error
4、赋值操作符
(1)例如:a=a+=10==a+=10
(2)复合赋值符
+=
-=
*=
/=
%=
>>=
<<=
&=
|=
=
这些运算符都可以写成复合的效果。
int x = 10;
x = x+10;
x+=10;// 复合赋值
// 其他运算符⼀一样的道理理。这样写更更加简洁。
5、单目操作符
! 逻辑反操作
- 负值
+ 正值
& 取地址
int a = 0;
Printf(“%p\n”,&a);//打印地址
Printf(“%x\n”,&a);//打印十六进制
sizeof 操作数的类型⻓长度(以字节为单位)
~ 对⼀一个数的⼆二进制按位取反
-- 前置、后置
-++ 前置、后置
++ * 间接访问操作符(解引⽤用操作符)
(类型) 强制类型转换
6、关系操作符
>
>=
<
<=
!= ⽤用于测试“不不相等”
== ⽤用于测试“相等”
7、逻辑操作符
&& 逻辑与
|| 逻辑或
8、条件操作符
exp1 ? exp2 : exp3
9、逗号表达式
exp1, exp2, exp3, …expN
(1) 逗号表达式,就是⽤用逗号隔开的多个表达式。
(2) 逗号表达式,从左向右依次执⾏行行。整个表达式的结果是【最后⼀一个表达式的结果。】
10、下标引⽤用、函数调⽤用和结构成员
(1)[ ]
操作数:⼀一个数组名 + ⼀一个索引值
int arr[10];// 创建数组
arr[9] = 10;// 实⽤用下标引⽤用操作符。
[ ]的两个操作数是arr和9
(2)( ) 函数调⽤用操作符 接受⼀一个或者多个操作数:第⼀一个操作数是函数名,剩余的操作数就是传递给函数的参数.
(3)访问⼀一个结构的成员
. 结构体.成员名
-> 结构体指针->成员名