操作符的存在使C语言更加的灵活,实现更多的功能。但是,操作符的一些繁琐的使用方式,规则却常常让我们这些初学者头疼。本文将操作符进行总结,汇总一起分享。
一,操作符的分类
操作符分为以下几种:算术操作符,位操作符,赋值操作符,单目操作符,关系操作符,逻辑操作符,条件操作符,逗号操作符,下标引用,函数调用和结构成员。
算术操作符:
+ - * / %
1.除了%操作符外,其他的操作符可以作用于整数和浮点数;
2.对于/操作符,如果有一个浮点数就执行浮点数除法;
3.%操作符的两个操作数必须是整数,返回整数相除之后的余数。
移位操作符
<< 左移操作符
>> 右移操作符
例如: int 型数据15在计算机里存储的是32位二进制数
00000000000000000000000000001111
15>>1即将二进制序列右移一位,右移出来的位丢掉,左边补符号位(算术移位)为
00000000000000000000000000000111
在部分编译器中右移会采用另一种逻辑移位,即左边用0补充,右边丢弃。
15<<1就是将二进制序列左移一位,左边移出来的位丢点,右边补0为
00000000000000000000000000011111
*注:*对于移位运算,不能移动负数位
即 num>>-1; //error
位运算符
& 按位与:同为1时为1,有0即为0;
| 按位或:有1即为1,同0才是0;
^ 按位异或 :同为0,异为1.
赋值运算符
= 可以给变量赋给你想要的值。
例如: int a = 10;
赋值运算符可以连续赋值使用,但是为了美观,清晰分开赋值更好一点。
还有种复合赋值赋,它在赋值运算符的基础上增加了一个运算的过程。
复合赋值符有:+= *= -= /= %= &= ^= |= >>= <<=
例如:a+=1;
与 a = a + 1;
表示同样的含义,执行同样的操作,其余复合运算符效果类似。
单目操作符
! 逻辑反操作
- 负值
- 正值
& 取地址
sizeof 操作数的类型长度(以字节为单位)
~ 对一个数的二进制按位取反
– 前置、后置–
++ 前置、后置++
- 间接访问操作符(解引用操作符)
(类型) 强制类型转换
*注:*sizeof() 是求变量(类型)所占空间的大小,单位是字节。
例如:sizeof( int ); //4
sizeof( char ); //2
求数组arr[]的元素个数时应该: sizeof(arr) / sizeof(arr[0]);
++ – 运算符在前置的时候是先++(–)再运算,而在后置是先运算在++(–)。
关系运算符
大于
大于等于
< 小于
<= 小于等于
!= 不相等
== 相等
逻辑运算符
&& 逻辑与
|| 逻辑或
&&执行时左边为0,便不执行右边返回0;
|| 执行时左边为1,就不执行后面返回1。
条件操作符
exp1 ? exp2 : exp3
若exp1满足则执行exp2否则exp3.
逗号表达式
exp1,exp2,exp3,……
逗号表达式从左到右依次执行,整个表达式的结果的最后一个表达式的结果。
下标引用、函数调用和结构成员
1.下标引用操作符 []
例如 : arr [ ];
2.函数调用操作符 ()
函数名 (参数)
3.结构成员操作符 . ->
访问一个结构体的成员。
#include <stdio.h>
struct Stu
{
char name[10];
int age;
char sex[5];
double score;
};
void set_age1(struct Stu stu)
{
stu.age = 18;
}
void set_age2(struct Stu* pStu)
{
pStu->age = 18;//结构成员访问
}
int main()
{
struct Stu stu;
struct Stu* pStu = &stu;//结构成员访问
stu.age = 20;//结构成员访问
set_age1(stu);
pStu->age = 20;//结构成员访问
set_age2(pStu);
return 0;
}
操作符的属性
复杂表达式的求值有三个影响的因素。
- 操作符的优先级
- 操作符的结合性
- 是否控制求值顺序。
两个相邻的操作符先执行哪个?取决于他们的优先级。如果两者的优先级相同,取决于他们的结合性。
操作符优先级