运算符
数学运算符
主要有加(+)减(-)乘(*)除(/)取余(%)
c
#include <stdio.h>
int main() {
int num;
num = 20;
printf("num is %d \n", num); // 20
// 加法
num = num + 5;
printf("num is %d \n", num); // 25
// 减法
num = num - 1;
printf("num is %d \n", num); // 24
// 除法
num = num / 3;
printf("num is %d \n", num); // 8
// 乘法
num = num * 4;
printf("num is %d \n", num); // 32
// 取余
num = num % 2;
printf("num is %d \n", num); // 0
}
赋值运算符
- 赋值: =
- 加等于: +=
- 减等于: -=
- 乘等于: *=
- 除等于: /=
c
#include <stdio.h>
int main() {
int num; // 声明但并未赋值
num = 20;
printf("num is %d \n", num); // 20
num += 5; // num = num + 5;
printf("num is %d \n", num); // 25
num -= 1; // num = num - 1;
printf("num is %d \n", num); // 24
num /= 3; // num = num / 3;
printf("num is %d \n", num); // 8
num *= 4; // num = num * 4;
printf("num is %d \n", num); // 32
num %= 2; // num = num % 2;
printf("num is %d \n", num); // 0
}
逻辑运算符
- 与: &&
- 或: ||
- 非: !
c
#include <stdio.h>
int main() {
int f = 0;
int t = 1;
printf("t && f = %d \n", t && f); // 0 -> false
printf("t || f = %d \n", t || f); // 1 -> true
printf("!f = %d \n", !f); // 1 -> true
printf("!t = %d \n", !t); // 0 -> false
}
位运算符
与运算 and
&
必须两个开关都为链接状态才能通电点亮灯泡, 用代码理解那就是必须两边都为 1 才为 1
c
#include <stdio.h>
int main() {
int t = 1 & 1;
printf("t is %d \n", t); // 1
int f = 1 & 0;
printf("f is %d \n", f); // 0
}
c
int r1 = 1 & 1; // 为什么结果是 1
int r2 = 4 & 5; // 为什么结果是 4
/*******************************
转二进制(1 & 1):
0 000 0001
0 000 0001
---------- 进行与运算 ----------
0 000 0001 -> 运算结果转十进制是 1
转二进制(4 & 5):
0 000 0100
0 000 0101
---------- 进行与运算 ----------
0 000 0100 -> 运算结果转十进制是 4
*********************************/
或运算 or
|
只要两个开关其中一个为链接状态就可以通电点亮灯泡, 用代码理解那就是两边只需要有一边为 1 就为 1
c
#include <stdio.h>
int main() {
int t1 = 1 | 1;
printf("t1 is %d \n", t1); // 1
int t2 = 1 | 0;
printf("t2 is %d \n", t2); // 1
}
c
int r1 = 1 | 0; // 为什么结果是 1
int r2 = 1 | 1; // 为什么结果是 1
int r3 = 2 | 3; // 为什么结果是 3
/*******************************
转二进制(1 | 0):
0 000 0001
0 000 0000
---------- 进行或运算 ----------
0 000 0001 -> 结果转十进制是 1
转二进制(1 | 1):
0 000 0001
0 000 0001
---------- 进行或运算 ----------
0 000 0001 -> 结果转十进制是 1
转二进制(2 | 3):
0 000 0010
0 000 0011
---------- 进行或运算 ----------
0 000 0011 -> 结果转十进制是 3
*******************************/
非运算 ~
!
只有当开关不链接的时候, 才能通电点亮灯泡, 否则会短路导致无法点亮灯泡
用代码理解, 1 取反为 0, 同理 0 取反 为 1
c
#include <stdio.h>
int main() {
int t = !0;
printf("t is %d \n", t); // 1
int f = !1;
printf("f is %d \n", f); // 0
}
c
int r1 = !0; // 为什么是 1
int r2 = !1; // 为什么是 0
int r3 = !3; // 位什么是 0
/********************************************
在 c 语言中, bool 类型用数字表示(1:真 0:假)
r1 = !0 -> 相当于其他语言的 r1 = !false -> 结果转bool值,所以是: 1
同理:
r2 = !1 -> 相当于其他语言的 r2 = !true -> 结果转bool值,所以是: 0
同理:
r3 = !3 -> 相当于其他语言的 r3 = !true -> 结果转bool值,所以是: 0
********************************************/
异或运算 xor
^
只有当两个开关链接在不同方向(必须一个向上一个向下)时才能通电点亮灯泡
用代码理解, 两个值不相等则为真否则为假
c
#include <stdio.h>
int main() {
int t1 = 0 ^ 1;
printf("t1 is %d \n", t1); // 1
int t2 = 1 ^ 0;
printf("t2 is %d \n", t2); // 1
int f1 = 1 ^ 1;
printf("f1 is %d \n", f1); // 0
int f2 = 0 ^ 0;
printf("f2 is %d \n", f2); // 0
}
c
int r1 = 3 ^ 5; // 为什么结果是 6
int r2 = 4 ^ 5; // 为什么结果是 1
int r3 = 2 ^ 2; // 为什么结果是 0
/*******************************
转二进制(3 ^ 5):
0 000 0011
0 000 0101
---------- 进行异或运算 ----------
0 000 0110 -> 结果转十进制是 6
转二进制(4 ^ 5):
0 000 0100
0 000 0101
---------- 进行异或运算 ----------
0 000 0001 -> 结果转十进制是 1
转二进制(2 ^ 2):
0 000 0010
0 000 0010
---------- 进行异或运算 ----------
0 000 0000 -> 结果转十进制是 0
*******************************/
位运算
位运算也叫位移运算, 主要有3个运算符:
移动操作符(关键字):
- 左移运算符:
<<
shl
- 右移运算符:
>>
shr
- 无符号右移运算符:
>>>
移动规律:
- 左移运算符: 空位补0, 符号位不变, 被移除的高位丢弃
- 右移运算符: 被移动的二进制右移动后, 最高位是0, 空位就补0, 最高位是1, 空位就补1
- 无符号右移运算符: 移动的二进制右移动后, 不管最高位是0还是1, 空缺位都补0
c
int r1 = 2 << 3; // 为什么是 16
int r2 = 12 >> 2; // 为什么是 3
c
// 1. 如何最快速度的计算 2 \* 8 的结果?
// 2. 如果最快速度计算 2 的 n 次方?
int x = 2 << 3; // 16
// 2 的 n 次方: 2 << (n-1)
// 2 的 5 次方: 2 << 4
int y = 2 << 4; // 32
计算机是如何进行运算?
c
#include <stdio.h>
int main() {
int n = 4 + 5;
printf("4 + 5 = %d \n", n); // 9
}
针对以上代码, 有一个简单的问题: 5 + 4 = 9 计算机是如何计算的?
计算机只懂二进制不懂十进制, 在二进制的世界里, 只有 0 和 1, 如何计算 4 + 5 呢?
计算机加法运算规则
- 将 4 和 5 转二进制
- 将两个数字进行异或运算
- 将两个数字进行与运算(如果结果为0, 则证明第一步计算的结果正确)
- 将与运算的结果, 左移一位
- 异或运算(第一步运算的结果和第三步运算的结果进行异或运算)
c
/**************************************
// 准备: 将两个数字转二进制:
4: 0000 0100
5: 0000 0101
// 第1步
0000 0100
0000 0101
------------ 异或运算
0000 0001
// 第2步: 如果结果为0, 则证明第一步计算的结果正确
0000 0100
0000 0101
------------ 与运算
0000 0100
// 第三步: 将与运算的结果, 左移一位
0000 0100
------------ 左移运算
0000 1000
// 第四步:(第一步运算的结果和第三步运算的结果进行异或运算
0000 0001
0000 1000
------------ 异或运算
0000 1001 -> 将结果转为十进制就是 9
// unbelievable!
// 经过上面的4个步骤, 终于得出了 4+5 的结果
**************************************/
如何实现 减法/乘法/除法
有了加法, 就能做减法, 乘法, 除法
- 减法的本质就是加法:
5 - 4 => 5 + (-4)
- 乘法的本质就是重复的做加法:
5 * 3 => 5 + 5 + 5
- 除法的本质就是重复的做减法:
6 / 2 => 6 - 2 - 2 - 2 => 6 + (-2) + (-2) + (-2)
流程控制
分支
if
c
#include <stdio.h>
int main() {
int n = 4 + 5;
if (n > 9) {
printf("n > 9");
} else if(n<9) {
printf("n < 9");
} else{
printf("n = 9");
}
}
switch
c
#include <stdio.h>
int main() {
int n = 4 + 5;
switch(n) {
case 1:
printf("n = 1");
break;
case 3:
printf("n = 3");
break;
case 5:
printf("n = 5");
break;
case 7:
printf("n = 7");
break;
case 9:
printf("n = 9");
break;
default:
printf("unknown value");
break;
}
}
循环
for
c
#include <stdio.h>
int main() {
int len = 10;
for (int i = 0; i < 10; i++) {
if (i == 2) {
continue;
}
if (i === 6) {
break;
}
printf("%d\n", i);
}
}
while
c
#include <stdio.h>
int main() {
int len = 10;
int i = 0;
while (i < len) {
i++;
if (i == 2) {
continue;
}
if (i == 6) {
break;
}
printf("%d\n", i);
}
}