summaryrefslogtreecommitdiff
path: root/docs/appendix-a.md
blob: 89e872c2637e4a8af640ea1dc130955d431323e5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
##关于软件的基础知识

> Copyright © 2002 Richard E.Buckman and Joshua Gay. 此文最早发布于 2002 年。

由 Richard E. Buckman 和 Joshua Gay 撰写

本节内容是特意为对计算机科学技术了解不多的人准备的。这节内容对于理解书中的文章和演讲并不是必须的,不过,它可以帮助那些不熟悉编程和计算机的人理解一些术语。

计算机*程序员*来写软件或者计算机程序。而程序可以认为是告诉计算机如何完成特定任务的一系列*指令*。你应该熟悉许多不同类型的应用程序:比如你的网页浏览器、你的文字处理器和你的邮件客户端等等。

程序最初的形态通常是*源代码*。这一系列高级指令由*编程语言*(比如 C 或者 Java)编写而成。之后会被一个名为*编译器*的工具编译为一种更底层的语言——*汇编语言*。另一种被称为*汇编器*的工具会将汇编代码分解为最终的*机器语言*——计算机可以*原生*理解的最底层代码。

![code](code.png)

例如,“Hello World”这个程序,通常是人们学习 C 语言时的第一个程序,编译和执行后会在屏幕上打印出“Hello World”[^1]。

```C
int main(){
	printf(''Hello World!'');
    return 0;
} 
```
在 Java 语言中,同样的程序会是这么写:

```Java
public class hello {
	public static void main(String args[]) {
		System.out.println(''Hello World!'');
    }
} 
``` 

然而用机器码表示,其中的一小部分可能会类似这样:

```
1100011110111010100101001001001010101110
0110101010011000001111001011010101111101
0100111111111110010110110000000010100100
0100100001100101011011000110110001101111
0010000001010111011011110111001001101100
0110010000100001010000100110111101101111
```

上面这段机器码就是基本的二进制形式。计算机中所有的数据都是由 0 或 1 组成的,但是人们很难理解这些数据。如果想要对二进制的值进行一个简单的更改,就不得不对特定计算机编译机器语言的原理了如指掌。这对于类似于上面这种小程序来说或许是可行的,但是对于任何有趣的程序,做一个简单的修改就需要耗费大量的精力。

比如说,如果我们想让让 C 语言编写的“Hello World”程序输出的英语“Hello World”变成法语。只需要做出简单的修改;新的程序如下:

```C
int main() {
    printf(''Bonjour, monde!'');
    return 0; 
}
```

It is safe to say that one can easily infer how to change the program
written in the Java programming language in the same way. However, even
many programmers would not know where to begin if they wanted to change
the binary representation. When we say “source code,” we do not mean
machine language that only computers can understand—we are speaking of
higher-level languages such as C and Java. A few other popular
programming languages are C++, Perl, and Python. Some are harder than
others to understand and program in, but they are all much easier to
work with compared to the intricate machine language they get turned
into after the programs are compiled and assembled.

因此同样也知道如何修改 Java 里面的这段代码了。然而更多的程序员不懂如何修改二进制形式。当我们说“源代码”的时候,不是指只有机器可以理解的机器码——我们指的是高级语言代码比如 C 或 Java 这种。其他的比如 C++、Perl 和 Python。有些比其他更难理解或编程,但都比理解编译和汇编以后的机器码简单多了。

Another important concept is understanding what an *operating system*
is. An operating system is the software that handles input and output,
memory allocation, and task scheduling. Generally one considers common
or useful programs such as the *Graphical User Interface* (GUI) to be a
part of the operating system. The GNU/Linux operating system contains a
both GNU and non-GNU software, and a *kernel* called *Linux*. The kernel
handles low-level tasks that applications depend upon such as
input/output and task scheduling. The GNU software comprises much of the
rest of the operating system, including GCC, a general-purpose compiler
for many languages; GNU Emacs, an extensible text editor with many, many
features; GNOME, the GNU desktop; GNU libc, a library that all programs
other than the kernel must use in order to communicate with the kernel;
and Bash, the GNU command interpreter that reads your command lines.
Many of these programs were pioneered by Richard Stallman early on in
the GNU Project and come with any modern GNU/Linux operating system.

另一个重要概念是理解*操作系统*。操作系统是控制输入输出,内存分配和任务调度的软件。而通常来说更有用的程序比如*图形用户界面*(*Graphical User Interface*,GUI)也是操作系统的一部分。GNU/Linux 包括了 GNU 和非 GNU 的软件,以及一个称为*Linux*的*内核*。内核负责处理底层任务比如输入输出和任务调度。GNU 软件包含了操作系统其余的大部分,比如 GCC,一个支持多种语言的通用编译器;GNU Emacs,一个可扩展的有很多很多特性的文本编辑器;GNOME,一个 GNU 桌面;GNU libc,除了内核以外,所有其他程序都需要与内核通讯的库;以及 Bash,GNU 命令行解释器可以读取你的命令。很多这些程序早期由理查德·斯托曼在 GNU 工程里开发,并成为现代 GNU/Linux 操作系统的组成部分。

It is important to understand that even if *you* cannot change the
source code for a given program, or directly use all these tools, it is
relatively easy to find someone who can. Therefore, by having the source
code to a program you are usually given the power to change, fix,
customize, and learn about a program—this is a power that you do not
have if you are not given the source code. Source code is one of the
requirements that makes a piece of software *free*. The other
requirements will be found along with the philosophy and ideas behind
them in this collection.

重要的是理解即使*你*没有修改一个程序的源代码的能力,也可以直接使用所有工具,这也比找到其他人能改更相对容易。因此,有源代码的程序你就有权力去修改、修复、个性化和学习编程——而如果得不到源代码就没有这些权力。源代码是让一个软件变*自由*的必要条件之一,而其他必要条件可从本书的哲学和理想中找到答案。

### [(1)](#DOCF1)

对于其他的编程语言,比如 Scheme,通常不从 Hello World 程序开始入门。在 Scheme 中,你通常会从这样的程序开始:

```lisp
(define (factorial n) 
  (if (= n 0) 
      1
      (* n (factorial (- n 1)))))
```

这段程序是求一个数的阶乘;也就是运行`(factorial 5)`将会输出 120,即 5 乘以 4 乘以 3 乘以 2 乘以 1。