一、算数操作符
算数操作符: + - * / %
- 除了
%
的操作数必须为整数,其他都可以为整数或者浮点数。 /
的两个操作数为整数,则执行整数除法,若是浮点数,则执行浮点数除法。
二、移位操作符
移位操作符的操作数只能是整数,移位不会改变数自身的值。
(一)左移操作符<<
移位规则:左边丢弃,右边补0。
(二)右移操作符>>
逻辑移位:右边丢弃,左边补0。
算数移位:右边丢弃,左边补原值相同的符号位。
补充:原码,反码,补码
正整数:原码,反码,补码相同,符号位为0。
负整数:反码符号位不变,其他按位取反,补码是二进制反码+1,符号位为1。
三、位操作符
位操作符的操作数只能是整数。
- 按位与
&
- 按位或
|
- 按位异或
^
:相同为0,相异为1。
利用按位异或^,实现不创建第三个变量,两个变量进行交互:
int main()
{
int num1 = 1;
int num2 = 2;
num1 = num1 ^ num2;
num2 = num1 ^ num2;
num1 = num1 ^ num2;
printf("%d %d", num1, num2);
return 0;
}
注意:因为num2^num2=0
,num1^0=num1
,^又满足交换律和结合律。
求取某个数二进制数中1的个数:
int main()
{
int num = -1;
int count = 0;
for (int i = 0; i < 32; i++)
{
if (((num>>i)&1) ==1)
{
count++;
}
}
printf("%d", count);
return 0;
}
注意:按照每次右移和1取&进行比较,判断每次右移的最后一位是0还是1。
int main()
{
int num = -1;
int count = 0;
while (num)
{
count++;
num = num & num - 1;
}
printf("%d", count);
return 0;
}
注意:num = num & num - 1
每做这样一次操作,就会减少二进制位中的1的个数一次。
四、赋值操作符
x=y=num+1;
这样赋值不如分开写简洁明了。- 复合赋值符:
+= -= *= /= %= >>= <<= &= |= ^=
五、单目操作符
!
:逻辑反操作,1变0,0变1-
:负值+
:正值&
:取地址sizeof
:操作数类型长度,以字节为单位,它不是函数,可以不用(),sizeof(int),必须有()
void test(char arr[])
{
printf("%d", sizeof(arr));
}
int main()
{
char arr[] = "abcdefg";
printf("%d\n", sizeof(arr));
test(arr);
return 0;
}
注意:第一个计算的是数组的大小8(有/0),第二个因为传递的是地址,计算的是地址变量的大小4(32位环境下地址是4个字节)。
~
:对一个数的二进制按位取反,配合左移位,可以产生1110111++ --
:前++先自增后赋值,后++先赋值后自增,–同理。
六、关系操作符
== != <= >= > <
,只需要在书写时,注意和赋值操作符的区别。
七、逻辑操作符
&& ||
注意逻辑短路:
int main()
{
int a = 0, b = 2, c = 3, d = 4;
int i = a++ && ++b && d++;
return 0;
}
注意:i=0,a=1,b=2,c=3,d=4。因为a++导致了逻辑与截断。
八、条件操作符和逗号表达式
- 条件操作符
exp1 ? exp2 : exp3
- 逗号表达式
exp1, exp2, ..., expn
,从左到右依次执行,最后一个表达式结果是整个表达式的结果。
while(a = get_val(),count_val(a),a>0)
{
;
}
九、下标引用、函数调用和结构体成员
- 下标引用操作符
[]
:一个数组名+一个索引值 - 函数调用操作符
()
:第一个操作数是函数名,剩余的操作数是传递给函数的参数。 - 访问结构体成员:
.
结构体变量.成员名,->
结构体指针->成员名。
十、整形提升和算数转换
(一)整形提升
字符和短整型操作数在进行CPU运算时,都会转化为普通整形。
整形提升是根据操作数的符号位来提升的,高位补符号位。
无符号数高位补0。
(二)算数转换
如果某个操作数与另一个不同类型的操作数进行操作,排名较低的操作数会转化为另一个操作数的类型再进行操作。
从高到低为:long double, double, float, unsigned long int, long int, unsigned int, int
#include <stdio.h>
int i;
int main()
{
i--;
if (i > sizeof(i))
{
printf(">\n");
}
else
{
printf("<\n");
}
return 0;
}
全局变量没有赋值为0,整数-1会算数转换为无符号整形,因为sizeof返回的是无符号整形。