Skip to content

运算符

数学运算符

主要有加(+)减(-)乘(*)除(/)取余(%)

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

and

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

or

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

not

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 ^

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 呢?

计算机加法运算规则

  1. 将 4 和 5 转二进制
  2. 将两个数字进行异或运算
  3. 将两个数字进行与运算(如果结果为0, 则证明第一步计算的结果正确)
  4. 将与运算的结果, 左移一位
  5. 异或运算(第一步运算的结果和第三步运算的结果进行异或运算)
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);
  }
}

Released under the MIT License.