分类
- 算术操作符
- 移位操作符
- 位操作符
- 赋值操作符
- 单目操作符
- 关系操作符
- 逻辑操作符
- 条件操作符
- 逗号表达式
- 下标引用,函数调用和结构成员
算数操作符
+ | 求两个数的和 |
---|---|
- | 求两个数的差 |
* | 求两个数的积 |
/ | 求两个数的商 |
% | 取模(两个数相除的余数) |
注意事项:
- 注意基本规则,如0不能做除数,这在编译时不会报错,但程序在执行时往往会出错。
- 除了 % 操作符之外,其他的几个操作符可以作用于整数和浮点数。
- 对于 / 操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法。
- % 操作符的两个操作数必须为整数。返回的是整除之后的余数。
移位操作符
左移操作符 | << |
---|---|
右移操作符 | >> |
- 左移操作符移位规则: 左边抛弃、右边补0
例如: 定义一个整型变量a;
int a = 5;
其二进制序列是:
0000 0000 0000 0000 0000 0000 0000 0101
左移一位的结果就是:
0000 0000 0000 0000 0000 0000 0000 1010 (a<<1) - 右移操作符移位规则:
首先右移运算分两种:
1. 逻辑移位 左边用0填充,右边丢弃
2. 算术移位 左边用原该值的符号位填充,右边丢弃
逻辑移位和左移类似
int a = 5;
其二进制序列是:
0000 0000 0000 0000 0000 0000 0000 0101
右移一位的结果就是:
0000 0000 0000 0000 0000 0000 0000 0010 (a>>1)
算数移位左边不能直接用0填充,要根据数据的符号位来决定
int a = -1;
其二进制序列(补码)是:
1111 1111 1111 1111 1111 1111 1111 1111
由于a是负数,在移位时右边填充的不是0,而是最高位的符号位:1;
所以右移一位的结果是:
1111 1111 1111 1111 1111 1111 1111 1111 (a>>1)
注意事项:
- 对于移位运算符,不能移动负数位,这个是标准未定义的
位操作符
& | 按位与 |
---|---|
丨 | 按位或 |
^ | 按位异或 |
& 按位与
0 & 0为0; 0 & 1 为0; 1 & 1为1;
int a = 5;
int b = 6;
二进制序列分别是:
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0000 0110
a & b的结果就是:
0000 0000 0000 0000 0000 0000 0000 0100
| 按位或
0 | 0为0; 0 | 1为1; 1 | 1为1;
int a = 5;
int b = 6;
a | b的结果就是:
0000 0000 0000 0000 0000 0000 0000 0111
^ 按位异或
0 ^ 0为0; 0 ^ 1为1; 1 ^ 1为0;
int a = 5;
int b = 6;
a ^ b的结果就是:
0000 0000 0000 0000 0000 0000 0000 0011
注意事项:
- 操作变量必须是整数
赋值运算符
=
把一个变量的值或者一个数值复制给另一个变量;
int a = 1;
把1赋值给a变量;
int b = a;
把a变量的值赋值给b变量;
赋值运算符可以连续使用(不推荐);
int c = b = a ;
复合赋值符
+= | “x += y” == “x = x + y” |
---|---|
-= | “x -= y” == “x = x - y” |
*= | “x *= y” == “x = x * y” |
/= | “x /= y” == “x = x / y” |
%= | “x %= y” == “x = x % y” |
>>= | “x >>= y” == “x = x >> y” |
<<= | “x <<= y” == “x = x << y” |
单目运算符
! | 逻辑反操作 |
---|---|
- | 负值 |
+ | 正值 |
& | 取地址 |
sizeof | 操作数类型长度(以字节为单位) |
~ | 对一个数的二进制按位取反 |
– | 前置,后置– |
++ | 前置,后置++ |
* | 间接访问操作符(解引用操作符) |
(类型) | 强制类型转换 |
注意事项:sizeof不是函数,是一个运算符!
关系操作符
> | 大于 |
---|---|
< | 小于 |
>= | 大于等于 |
<= | 小于等于 |
!= | 不相等 |
== | 等于 |
注意事项:不要将“==”和“=”搞混了!
逻辑运算
&& | 逻辑与 |
---|---|
丨 | 逻辑或 |
逻辑与 && ,当 && 符号两边表达式的值都为真的时候,结果为真;否则都为假。
逻辑或 || ,当 || 符号两边表达式的值都为0的时候,结果为假;否则都为真。
注意事项:
&&在运算时,从左到右依次判断,如果左边的表达式为假;则不会再判断右边的表达式(如果右边是一个赋值表达式,也不会被止执行)。
同理,||在运算时如果左边的表达式为真,则不会再判断右边的表达式
条件运算符
exp1 ? exp2 : exp3
若exp1的值为真,则执行exp2,否则执行exp3。
逗号表达式
逗号表达式,就是用逗号隔开的多个表达式。从左向右依次执行。整个表达式的结果是最后一个表达式的结果。
int a = 2;
int b = 3;
int c = (a, b, a + b);
执行结束后c的值为5;
下标引用、函数调用和结构成员
- 1 . [ ] 下标引用操作符 操作数:一个数组名 + 一个索引值
int a[10];
a[0] = 1;
对数组元素进行引用
2 . ( )函数调用操作符 接受一个或者多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数
#include <stdio.h>
void test1()
{
printf("hehe\n");
}
void test2(const char *str)
{
printf("%s\n", str);
}
int main()
{
test1(); //实用()作为函数调用操作符。
test2("hello bit.");//实用()作为函数调用操作符。
return 0;
}
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;
}