操作符分类
1.算术操作符
2.移位操作符
3.位操作符
4.赋值操作符
5.单目操作符
6.关系操作符
7.逻辑操作符
8.条件操作符
9.逗号表达式
10.下标引用、函数调用和结构成员
算术操作符
+ - * /
- 除了% 操作符之外,其他的几个操作符可以作用于整数和浮点数。
- 对于/ 操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法。
- % 操作符的两个操作数必须为整数。返回的是整除之后的余数。
移位操作符
>> 右移操作符 右边丢弃,左边补原符号位
<< 左移操作符 左边丢弃,右边补0
注:移位操作符的操作数只能为整数
原码:直接根据数值写出的二进制序列就是原码
反码:原码符号位不变,其他位按位取反就是反码
补码:反码+1,就是补码
注:正整数的原、反、补码相同
位操作符
& 按位与 二进制的相同位 同为1结果才为1,其余为0
| 按位或 二进制的相同位 有1结果则为1,其余为0
^ 按位异或 二进制的相同位 相同为0,相异为1
赋值操作符
= += -= *= /= %=
注:= —— 赋值
== —— 判断等于
单目操作符
! - + & sizeof ~ ++ --- * (类型)
sizeof中的表达式是不参与运算的!
a++,后置++:先使用,后++
++a,前置++:先++,后使用
a--,后置--:先使用,后--
--a,前置--:先--,后使用
int main()
{
int a=10;
int b=a++;
printf("%d\n",a);//11
printf("%d\n",b);//10
return 0;
}
int main()
{
int a=10;
int b=++a;
printf("%d\n",a);//11
printf("%d\n",b);//11
return 0;
}
关系操作符
> >= < <= != ==
逻辑操作符
&& 按位与
|| 按位或
360笔试题:
int main()
{
int i = 0, a = 0, b = 2, c = 3, d = 4;
i = a++ && ++b && d++;
printf("a = %d\nb = %d\nc = %d\nd = %d\n", a, b, c, d);
return 0;
}
//程序输出的结果是什么?
a=1
b=2
c=3
d=4
int main()
{
int i = 0, a = 0, b = 2, c = 3, d = 4;
i = a++||++b||d++;
printf("a = %d\nb = %d\nc = %d\nd = %d\n", a, b, c, d);// 1 3 3 4
return 0;
}
//程序输出的结果是什么?
a=1
b=3
c=3
d=4
条件操作符(三目操作符)
exp1 ? exp2 : exp3
max=(a>b? a : b);
逗号表达式
逗号表达式:要从左向右依次计算,但是整个表达式的结果是最后一个表达式结果
int a=3;
int b=5;
int c=0;
int d=(c=5,a=c+3,b=a-4,c+=5);
printf("%d",d);
//d的结果为10
下标引用、函数调用和结构成员
[] —— 下标引用操作符
() —— 函数调用操作符
结构成员访问操作符:
.
struct Book
{
//结构体的成员(变量)
char name[20];
char id[20];
int price;
};
int main()
{
//结构体变量名.成员名
struct Book b = { "C语言","202110530116",55 };
printf("书名:%s\n", b.name);
printf("书号:%s\n", b.id);
printf("定价:%d\n", b.price);
return 0;
}
->
struct Book
{
//结构体的成员(变量)
char name[20];
char id[20];
int price;
};
int main()
{
//结构体指针->成员名
struct Book b = { "C语言","202110530116",55 };
struct Book* pb = &b;
printf("书名:%s\n", pb->name);
printf("书号:%s\n", pb->id);
printf("定价:%d\n", pb->price);
return 0;
}
隐式类型转换
1.关于整形提升的问题(char、short类型)
有符号位:整形提升的高位补的是符号位
无符号位:整形提升的高位补0
int main()
{
char a = 3;
//00000000000000000000000000000011
//00000011 - a
char b = 127;
//00000000000000000000000001111111
//01111111 - b
char c = a + b;
//发现a和b都是char类型的,都没有达到一个int类型的大小
//这里就会发生整形提升
//00000000000000000000000000000011
//00000000000000000000000001111111
//00000000000000000000000010000010
//10000010 - c
//这里打印int类型的c要发生整形提升
//11111111111111111111111110000010 - 补码
//11111111111111111111111110000001 - 反码
//10000000000000000000000001111110 - 原码
printf("%d", c);//-126
return 0;
}
int main()
{
char a = 0xb6;
short b = 0xb600;
int c = 0xb6000000;
if (a == 0xb6)
printf("a");
if (b == 0xb600)
printf("b");
if (c == 0xb6000000)
printf("c");
return 0;
//打印了一个c
//a和b都存不下原数据,而c可以
}
int main()
{
//表达式参与运算,发生了整形提升
char c = 1;
printf("%u\n", sizeof(c));//1
printf("%u\n", sizeof(+c));//4
printf("%u\n", sizeof(-c));//4
printf("%u\n", sizeof(!c));//4
return 0;
}
signed char类型的范围是:-128—127 在八位二进制中把-0当作最小数-128用,也就是10000000
unsigned char类型的范围是:0—255
2.算术转换
如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数的转换为另一个操作数的类
型,否则操作就无法进行。下面的层次体系称为寻常算术转换。
long double
double
float
unsigned long int
long int
unsigned int
int
如果某个操作数的类型在上面这个列表中排名较低,那么首先要转换为另外一个操作数的类型后执行运算。