如果你从未接触过C语言, 那么我建议你先阅读前面的文章:
操作符
在认识条件分支和循环语句的文章↗中, 介绍了逻辑运算符&& || !
和关系运算符== != >= <= > <
这两类运算符是C语言操作符的一部分
什么是操作符
操作符(Operator) 是C语言中用于对数据(变量、常量等)执行特定操作的符号或关键字
简单来说, C语言中的操作符就是用来操作数据的, 特定的操作符可以对数据实现特定的操作
操作符介绍
C语言存在许多操作符, 本篇文章只做简单介绍, 某些操作符的具体使用方法, 在之后的文章中会涉及
算术运算符
C语言提供的算术运算符有:
运算符 | 功能 | 示例 |
---|---|---|
+ | 加, 实现两数相加 | 1 + 1 => 2 |
- | 减, 实现两数相减 | 1 - 1 => 0 |
* | 乘, 实现两数相乘 | 2 * 2 => 4 |
/ | 除, 实现两数相除 | 2 / 2 => 1 |
% | 模, 取模, 即对整数求余数 | 5 % 2 => 1 |
移位运算符
移位运算符, 顾名思义是操作在数据的二进制层面的, 用于对数据二进制位进行左移和右移
运算符 | 功能 | 示例 |
---|---|---|
<< | 左移位操作符, 实现将数据二进制位向左移动 | 1 << 2 => 4 |
>> | 右移位操作符, 实现将数据二进制位向右移动 | 8 >> 2 => 2 |
移位操作符, 就是将数据 在二进制位的层面上 向左或向右移动n
位
移位操作符可能有一些抽象, 如果对二进制不是很了解, 可能不容易理解
不过也可以通过例子简单理解一下:
/*
* 以 4(int) 为例
* 4 的 二进制是 00000000 00000000 00000000 00000100 (32位)
* 4 << 5, 就是 二进制位左移5位, 得:
* 00000000 00000000 00000000 00000000 10000000, 128
*
* 4 >> 2, 就是 二进制位右移2位, 得:
* 00000000 00000000 00000000 00000000 00000001, 1
*/
有关移位操作还有一些细节与数据类型有关, 暂不做更多分析
但要注意, <<
左移时 移动的位数只能小于数据类型大小, 否则就是C语言标准未定义的行为, 会出现未知的问题
// 左移的错误例子
#include <stdio.h>
int main() {
int age = 2;
printf("%u\n", age << 32);
return 0;
}
如果左移位数不小于数据类型的大小, 编译时也会提醒
位运算符
位操作符, 也是操作在数据的二进制层面的, 但并不是移动:
运算符 | 功能 | 示例 |
---|---|---|
& | 按位与, 对两数二进制位执行与操作, 对应位置均为1, 结果位才为1 | 2 & 3 => 2 |
| | 按位或, 对两数二进制位执行或操作, 对应位置均为0, 结果位才为0 | 2 | 4 => 6 |
~ | 按位取反, 对数据二进制位执行取反操作, 对数据每位进行取反操作, 即 1变0, 0变1 | ~1 => -2 (有符号) |
^ | 按位异或, 对两数二进制数据执行异或操作, 对应位置不同, 结果位才为1 | 2 ^ 3 => 1 |
位操作符, 比移位操作符要更加抽象一些, 不过依旧可以通过例子进行理解:
/*
* 以 4(int) 和 7(int) 为例
* 4: 00000000 00000000 00000000 00000100
* 7: 00000000 00000000 00000000 00000111
*
* 4 & 7 (与):
* 00000000 00000000 00000000 00000100
* 00000000 00000000 00000000 00000111
* -----------------------------------
* 00000000 00000000 00000000 00000100 (对应位均为1, 结果位才为1)
*
* 4 | 7 (或):
* 00000000 00000000 00000000 00000100
* 00000000 00000000 00000000 00000111
* -----------------------------------
* 00000000 00000000 00000000 00000111 (对应位均为0, 结果位才为0)
*
* 4 ^ 7 (异或):
* 00000000 00000000 00000000 00000100
* 00000000 00000000 00000000 00000111
* -----------------------------------
* 00000000 00000000 00000000 00000011 (对应位不同, 结果位才为1)
*
* ~4 (取反);
* 00000000 00000000 00000000 00000100
* -----------------------------------
* 11111111 11111111 11111111 11111011 (对应位取反)
*/
仔细观察一下, 比较容易理解的
赋值运算符
C语言提供了赋值运算符, 可以给变量赋值: =
用法很简单:
#include <stdio.h>
int main() {
int age;
age = 20;
printf("%d\n", age);
return 0;
}
这段代码, age = 20;
给age
变量赋值20
除此之外, C语言还提供了一些赋值运算符的扩展, 被称为复合赋值运算符:
运算符 | 功能 | 示例 | 等价形式 |
---|---|---|---|
= | 赋值,将右侧的值 赋给左侧变量 | a = 5; | a = 5; |
+= | 加后赋值,左侧变量 加 右侧值 再赋给左侧 | a += 3; | a = a + 3; |
-= | 减后赋值,左侧变量 减 右侧值再赋给左侧 | a -= 2; | a = a - 2; |
*= | 乘后赋值,左侧变量 乘 右侧值 再赋给左侧 | a *= 4; | a = a * 4; |
/= | 除后赋值,左侧变量 除以 右侧值 再赋给左侧 | a /= 2; | a = a / 2; |
%= | 取模后赋值,左侧变量 对 右侧值取模 再赋给左侧 | a %= 3; | a = a % 3; |
&= | 按位与后赋值,左侧变量 与右侧值按位与 再赋给左侧 | a &= b; | a = a & b; |
` | =` | 按位或后赋值,左侧变量 与右侧值按位或 再赋给左侧 | `a |
^= | 按位异或后赋值,左侧变量 与右侧值按位异或 再赋给左侧 | a ^= b; | a = a ^ b; |
<<= | 左移后赋值,左侧变量 左移 右侧值位 再赋给左侧 | a <<= 2; | a = a << 2; |
>>= | 右移后赋值,左侧变量 右移 右侧值位 再赋给左侧 | a >>= 1; | a = a >> 1; |
在不考虑编译器额外优化的情况下, 使用复合赋值运算符要比正常的计算后赋值, 运行效率要高一点
单目操作符
单目操作符, 从名字来看 看不出是什么意思
事实上, 单目操作符就是操作单个对象的操作符
什么是操作单个对象呢?
以之前用过的计算变量大小的操作符为例: sizeof
sizeof
的用法是这样的:
sizeof(int); // 操作类型
sizeof(1.23f); // 操作数据
long long age = 10;
sizeof(age); // 操作变量
可以看到, 操作的对象只有一个
上面已经介绍过的算术、移位、位、赋值运算符都是双目操作符, 他们操作的都是两个对象