# 重新定义C语言

## 计算机硬件

x86, MIPS, 指令执行，状态机模型。

## C Runtime作为抽象计算机

> 为什么需要C？因为硬件太复杂，人理解不了。

指令集设计成现在这个样子，很大程度上兼顾了历史包袱(兼容性)、执行速度、硬件实现的代价和可行性等。在这几个目标之间，满足“好编程”这件事情就不那么重要了。

C定义了“内存”，一个字节数组。

PC和内存就可以定义C语言的semantics。

(PC, M) => (PC1, M1) => ...

这就对应了我们“阅读程序写结果”。有些行为是undefined，比如越界、溢出等等。

## C AM在硬件上的执行

(x86为例)

硬件会维护M，但也会有一些附加的状态(比如寄存器)，但总体来说，(PC, M)是一定有的，这样人类才能理解的了程序的行为。

编译器未必严格按照语义的“步骤”执行，比如

    for (int i = 1; i <= 100; i++) sum += i;

可以被优化成

    sum += 5050;

但总有一个点语义会能对应上。

C的一个很大的优势就在于，他相对于硬件比较低级，有内存，所以很多时候能“看到汇编”，从而能控制机器的行为。也很容易搞砸(UB)。
