文章目录
运算符
赋值运算符
运算符 | 含义 |
---|---|
= | 赋值运算符,将右边的值赋给左边 |
+= | 加等于,将右边的值加到左边 |
-= | 减等于,将右边的值减去左边 |
*= | 乘等于,将右边的值乘以左边 |
/= | 除等于,将右边的值除以左边 |
%= | 取模等于,将右边的值取模到左边 |
赋值运算符支持基本数据类型,包括char,short,int,long,float,double,字符串(字符数组)不能使用赋值运算符
算术运算符
运算符 | 含义 |
---|---|
+ | 加,将两个数相加 |
- | 减,将两个数相减 |
* | 乘,将两个数相乘 |
/ | 除,将两个数相除 |
% | 取模,将两个数取余 |
++ | 自增,将一个数加1 |
– | 自减,将一个数减1 |
变量的自增或自减有两种写法:
变量名++ ,表示在本次使用变量后再自增
++变量名 ,表示在本次使用变量前自增
变量名– ,表示在本次使用变量后再自增
–变量名 ,表示在本次使用变量前自减
关系运算符
运算符 | 含义 |
---|---|
== | 等于,比较两个数是否相等 |
!= | 不等于,比较两个数是否不相等 |
> | 大于,比较两个数是否大于 |
< | 小于,比较两个数是否小于 |
>= | 大于等于,比较两个数是否大于等于 |
<= | 小于等于,比较两个数是否小于等于 |
关系运算符的结果是布尔值,即0或1
逻辑运算符
运算符 | 含义 |
---|---|
&& | 逻辑与,两个数都为真时才为真 |
|| | 逻辑或,两个数有一个为真时才为真 |
! | 逻辑非,取反 |
短路
逻辑运算符自左向右计算
如果遇到逻辑与运算符&&,当左边的表达式为假时,直接返回结果,不再计算右边的表达式
如果遇到逻辑或运算符||,当左边的表达式为真时,直接返回结果,不再计算右边的表达式
逗号运算符
一条语句理论上是有返回值的,如果语句里面有多个逗号,则以最后一个逗号后面的表达式值为返回值
条件运算符
条件运算符是三目运算符,形式为:
表达式1 ? 表达式2 : 表达式3
先执行表达式1,如果表达式1的结果如果为真,那么执行表达式2,并且这个整体的运算式的结果是表达式2的结果;如果表达式1的结果如果为假,执行表达式3,运算式的结果是表达式3的结果
三目运算可以嵌套,但不建议嵌套,过于复杂
sizeof运算符
sizeof是C语言中的一个关键字,不是一个函数,用于计算数据类型所占用的内存空间大小
用于数据类型
sizeof(数据类型);
用于变量名
sizeof(变量名);
sizeof 变量名;
还有sizeof(结构体),会在结构体的文章中提及
不要对void类型使用sizeof
void是无值型或空类型,不知道存储空间大小的类型,编译器也不能确定它的大小
void不能声明变量,以下代码编译无法通过
void a;
但可以声明指针变量
void *p;
printf("sizeof(void*)= %d\n", sizeof(p));
输出结果为:sizeof(void*)= 8
指针的大小通常是4个字节或8个字节
不要在子函数中对字符指针使用sizeof
如果把一个字符串(如char strname[21])的地址传给子函数,子函数用一个字符指针(如char *pstr)来存放传入的字符串的地址,如果在子函数中用sizeof(pstr),得到的不是字符串占用内存的字节数,而是字符指针变量占用内存的字节数(8字节)。
所以,不能在子函数中对传入的字符串进行初始化,除非字符串的长度也作为参数传入到了子函数中
不要在子函数中对结构体指针使用sizeof
如果把一个结构体(如struct st_girl stgirl)的地址传给子函数,子函数用一个结构体指针(如struct st_girl *pgril)来存放传入的结构体的地址,如果在子函数中用sizeof(pgirl),得到的不是结构体占用内存的字节数,而是结构体指针变量占用内存的字节数(8字节)。
正确的用法是用sizeof(struct st_girl)
不要在子函数中对数组指针使用sizeof
如果把一个数组(如int arr[10])的地址传给子函数,子函数用一个数组指针(如int *parr)来存放传入数组的地址,如果在子函数中用sizeof(parr),得到的不是数组占用内存的字节数,而是数组指针变量占用内存的字节数(8字节)。
正确的用法是用sizeof(arr)/sizeof(arr[0])
位运算符
按位与&
如果(x)i == 1,(y)i == 1,则(x&y)i == 1,否则(x&y)i == 0
按位或|
如果(x)i == 1或(y)i == 1,则(x|y)i == 1,否则(x|y)i == 0
按位取反~
如果(x)i == 1,则(~x)i == 0,(x)i == 0,则(~x)i == 1
按位异或^
如果(x)i == (y)i,那么(x^y)i == 0,否则(x^y)i == 1,如果两个位相等,那么结果为零,如果不相等,结果为1
对一个变量用同一个值异或两次,结果不变
按位左移<<
i << j,将i中所有的位向左移动j个位置,而右边填入0,所有小于int的类型位移以int的方式来做,结果是int类型
x << 1 等价于 x *= 2
x << n 等价于 x *= 2^n
按位右移>>
i >> j,将i中所有的位向右移动j个位置,所有小于int的类型位移以int的方式来做,结果是int类型
对于unsigned类型,右移时,高位补0
对于signed类型,右移时,高位补符号位
x >> 1 等价于 x /= 2
x >> n 等价于 x /= 2^n
运算符的优先级
优先级 | 运算符 | 名称含义 | 结合方向 | 说明 |
---|---|---|---|---|
1 | [ ] | 数组成员 | 从左到右 | 数组名[下标] |
1 | ( ) | 表达式 | 从左到右 | 函数名(实参列表)/(表达式) |
1 | . | 成员选择(对象) | 从左到右 | 结构体变量.成员名 |
1 | -> | 成员选择(指针) | 从左到右 | 结构体指针->成员名 |
2 | - | 负号 | 从右到左 | 单目运算符 |
2 | ~ | 按位取反 | 从右到左 | 单目运算符 |
2 | ++ | 自增 | 从右到左 | 单目运算符 |
2 | – | 自减 | 从右到左 | 单目运算符 |
2 | * | 指针取值 | 从右到左 | 单目运算符 |
2 | & | 取地址 | 从右到左 | 单目运算符 |
2 | ! | 非 | 从右到左 | 单目运算符 |
2 | sizeof | 计算内存 | 从右到左 | |
2 | (类型) | 强制类型转换 | 从右到左 | |
3 | * | 乘法 | 从左到右 | 双目运算符 |
3 | / | 除法 | 从左到右 | 双目运算符 |
3 | % | 取余 | 从左到右 | 双目运算符 |
4 | + | 加法 | 从左到右 | 双目运算符 |
4 | - | 减法 | 从左到右 | 双目运算符 |
5 | << | 左移 | 从左到右 | 双目运算符 |
5 | >> | 右移 | 从左到右 | 双目运算符 |
6 | < | 小于 | 从左到右 | 双目运算符 |
6 | <= | 小于等于 | 从左到右 | 双目运算符 |
6 | > | 大于 | 从左到右 | 双目运算符 |
6 | >= | 大于等于 | 从左到右 | 双目运算符 |
7 | == | 等于 | 从左到右 | 双目运算符 |
7 | != | 不等于 | 从左到右 | 双目运算符 |
8 | & | 按位与 | 从左到右 | 双目运算符 |
9 | ^ | 按位异或 | 从左到右 | 双目运算符 |
10 | | | 按位或 | 从左到右 | 双目运算符 |
11 | && | 逻辑与 | 从左到右 | 双目运算符 |
12 | || | 逻辑或 | 从左到右 | 双目运算符 |
13 | ? : | 条件运算符 | 从右到左 | 三目运算符 |
14 | = | 赋值 | 从右到左 | |
14 | += | 加法赋值 | 从右到左 | |
14 | -= | 减法赋值 | 从右到左 | |
14 | *= | 乘法赋值 | 从右到左 | |
14 | /= | 除法赋值 | 从右到左 | |
14 | %= | 取余赋值 | 从右到左 | |
14 | <<= | 左移赋值 | 从右到左 | |
14 | >>= | 右移赋值 | 从右到左 | |
14 | &= | 按位与赋值 | 从右到左 | |
14 | ^= | 按位异或赋值 | 从右到左 | |
14 | |= | 按位或赋值 | 从右到左 | |
15 | , | 逗号运算符 | 从左到右 |