The First Programming Languages: Crash Course Computer Science #11
Summary
TLDR这一集的CrashCourse计算机科学课程由Carrie Anne主持,深入探讨了软件的发展历史。起初,编程工作非常繁琐且不灵活,因为需要直接在硬件层面上使用机器语言进行编程。为了简化编程过程,程序员开始寻求更通用的方法,于是软件的概念应运而生。视频介绍了机器语言、汇编语言、以及高级编程语言的发展历程。重点讲述了Grace Hopper博士对高级编程语言的贡献,以及她设计的编译器如何将源代码转换为机器代码。此外,还提到了FORTRAN和COBOL等早期高级语言,它们如何极大地降低了编程的门槛,使计算机科学从专家领域转变为广泛的通用工具。最后,视频展望了编程语言设计的黄金时代,以及它们如何与计算机硬件的进步同步发展,从而让更多人能够快速地实现更伟大的成就。
Takeaways
- 💾 硬件层面编程既繁琐又缺乏灵活性,因此程序员寻求更通用的编程方式,即软件。
- 📏 在设计的CPU中,指令的前四位是操作码(OPCODE),如0010表示LOAD_A指令,将值从内存移动到寄存器A。
- 🔢 计算机硬件只能处理原始的二进制指令,这是机器语言或机器代码,早期编程需要完全使用机器代码。
- 📝 程序员首先在纸上用高级语言(如英语)编写程序,称为伪代码,然后手动将其转换为二进制机器代码。
- 🚀 20世纪40年代末至50年代,程序员开发了更易读的高级语言,使用助记符代替操作码,如LOAD_A 14。
- 🔩 汇编器是将文本指令转换为二进制指令的程序,它隐藏了不必要的复杂性,使编程更容易。
- 🔗 汇编语言与机器代码有直接的一对一映射,因此与底层硬件紧密相关,但仍然要求程序员考虑寄存器和内存位置。
- 🤔 格蕾丝·霍珀博士设计了一种高级编程语言A-0,并在1952年构建了第一个编译器,将源代码转换为低级语言或机器代码。
- 🔑 FORTRAN是IBM在1957年发布的编程语言,它比手写的汇编代码短20倍,并且由编译器转换为机器代码。
- 📈 COBOL是一种高级、易于使用的编程语言,旨在跨不同计算机使用,它实现了“一次编写,到处运行”的概念。
- 🌐 高级编程语言的出现降低了计算机领域的入门门槛,使科学家、工程师、医生等能够将计算融入工作。
- 📚 从20世纪60年代到新千年,出现了多种编程语言,如ALGOL、LISP、BASIC、Pascal、C、Smalltalk、C++、Objective-C、Perl、Python、Ruby和Java等。
Q & A
为什么硬件层面的编程被认为是笨重和不灵活的?
-硬件层面的编程直接使用机器语言,这是一种由0和1组成的二进制指令,对人类来说难以阅读和编写。它缺乏高层次的抽象,使得编程工作变得复杂且容易出错,同时也难以适应程序需求的变化。
在计算机科学中,什么是操作码(OPCODE)?
-操作码(OPCODE)是机器语言指令中的前四个比特,用来指定计算机执行的操作类型。例如,在假设的CPU中,操作码0010代表LOAD_A指令,即将内存中的值移动到寄存器A。
什么是伪代码(Pseudo-Code)?
-伪代码是一种非正式的、高层次的程序描述,通常用英语或其他人类语言编写,用来描述程序的逻辑和步骤,而不涉及具体的编程语言细节。它帮助程序员在编写具体的机器代码之前,先在纸上设计和理解程序的流程。
汇编器(Assembler)的主要功能是什么?
-汇编器的主要功能是读取用汇编语言编写的程序,并将这些文本指令转换成对应的机器代码。它通过这种方式,使得程序员可以使用更容易理解的助记符和标签来编写程序,而不是直接使用复杂的二进制机器代码。
为什么汇编语言仍然与底层硬件紧密相关?
-汇编语言中的每条指令通常直接对应于机器指令,形成一对一的映射关系,因此它与特定的硬件架构紧密相关。汇编语言的程序员需要考虑具体的寄存器和内存位置,这限制了程序的可移植性,并要求对硬件有一定的了解。
Grace Hopper博士设计了哪种高级编程语言?
-Grace Hopper博士设计了一种名为“A-0”的高级编程语言,这是为了提高编程的效率和可读性,减少对底层硬件操作的依赖。
什么是编译器(Compiler)?
-编译器是一种特殊的程序,它能够将用高级编程语言编写的“源代码”转换成低级语言,如汇编语言或CPU能直接处理的二进制机器代码。编译器的出现极大地简化了编程过程,使得程序员可以更加专注于程序逻辑而非底层实现。
FORTRAN编程语言是如何影响早期计算机编程的?
-FORTRAN(Formula Translation的缩写)是由IBM在1957年发布的,它在早期计算机编程中占据主导地位。FORTRAN语言的平均程序长度比手写的汇编代码短20倍,而且FORTRAN编译器能够将这些代码转换成机器代码。尽管社区最初对它的性能持怀疑态度,但由于程序员能够更快地编写更多的代码,它在经济上是一个容易的选择。
COBOL语言的主要特点是什么?
-COBOL(Common Business-Oriented Language的缩写)是一种高级、易于使用的编程语言,它允许程序员一次编写代码,然后在不同的计算机上运行,而不需要针对每种硬件重新编写代码。这种特性被称为“一次编写,到处运行”(write once, run anywhere),它减少了对特定硬件的依赖,提高了代码的可移植性。
高级编程语言的出现如何降低了计算机领域的入门门槛?
-高级编程语言的出现使得非计算机专家和爱好者,如科学家、工程师、医生、经济学家和教师等,都能够将计算纳入他们的工作。这些语言通过提供更高层次的抽象,隐藏了底层的复杂性,使得编程变得更加容易和可访问,从而降低了计算机领域的入门门槛。
编程语言设计中的“黄金时代”是指什么时期?
-编程语言设计中的“黄金时代”指的是20世纪60年代至90年代,这一时期出现了许多重要的编程语言,如ALGOL、LISP、BASIC、Pascal、C、Smalltalk、C++、Objective-C、Perl、Python、Ruby和Java等。这些语言的出现与计算机硬件的显著进步并行,推动了编程语言设计的快速发展。
为什么说编程语言的抽象能力对于创建复杂程序至关重要?
-编程语言的抽象能力允许程序员创建复杂的程序而不必深陷底层硬件细节。这种抽象使得程序员能够使用更接近自然语言的构造来表达算法和逻辑,从而减少了编写、维护和理解代码的工作量。高级编程语言的这种特性使得创建需要数百万甚至数千万行汇编代码的复杂程序成为可能。
Outlines
📚 计算机软件的起源与机器语言
本段落介绍了计算机科学的硬件基础,包括电力、电路、寄存器、RAM、算术逻辑单元(ALU)和中央处理器(CPU)。随后讨论了硬件编程的局限性,即其繁琐和缺乏灵活性,因此程序员寻求更高效的方式来编程,即软件。通过一个简单程序的示例,解释了机器语言的概念,包括操作码(OPCODE)和内存地址的概念。此外,还提到了伪代码(Pseudo-Code)的概念,以及汇编器(Assembler)的发明,它允许程序员使用更易读的文本指令来代替二进制机器代码,从而简化了编程过程。
🔍 汇编语言与高级编程语言的发展
该段落讲述了汇编语言虽然比机器语言更易于理解,但仍然与硬件紧密相关,并且需要程序员考虑寄存器和内存位置。接着,介绍了Grace Hopper博士和她的A-0编程语言,这是高级编程语言的早期形式,以及编译器的诞生,它能够将高级语言代码转换为机器代码。随后,IBM推出的FORTRAN语言成为早期计算机编程的主导语言。此外,还提到了COBOL语言的发展,它允许在不同计算机架构上使用相同的源代码,实现了“一次编写,到处运行”的理念。最后,强调了高级编程语言如何降低了计算机使用的门槛,使更多的人能够将计算融入到他们的工作中。
🚀 编程语言的未来与智能化
本段落探讨了编程语言的未来,提出了使用“普通英语”进行编程的终极目标,即通过自然语言与计算机交互。虽然这样的智能系统目前还是科幻小说中的概念,但未来的发展可能会实现这一点。同时,提到了CuriosityStream这个流媒体服务,它提供了大量纪录片和非虚构作品,包括关于互联网的系列节目“Digits”。最后,鼓励观众继续关注接下来的几集,以深入理解编程语言和软件如何实现酷炫和不可思议的事情。
Mindmap
Keywords
💡硬件
💡软件
💡机器语言
💡伪代码
💡汇编语言
💡汇编器
💡抽象
💡编译器
💡FORTRAN
💡COBOL
💡编程语言发展
Highlights
本集由CuriosityStream赞助,Carrie Anne主持,讨论了计算机科学的硬件和软件。
早期编程在硬件层面上非常繁琐和不灵活,因此程序员寻求更通用的编程方式。
介绍了软件的概念,以及它如何作为编程计算机的“更软”介质。
通过CPU设计的简单程序,解释了指令的二进制表示和操作码(OPCODE)。
说明了如何将高级程序伪代码转换为机器代码,并手动进行二进制编码。
20世纪40年代末到50年代,程序员开发了更易读的高级语言,并引入了助记符。
介绍了汇编器(Assembler)的概念,它将文本指令转换为二进制机器代码。
汇编器通过自动计算跳转地址和使用标签简化了编程过程。
尽管汇编语言提供了便利,但它仍然与机器代码紧密相关,并且需要程序员考虑底层硬件。
Grace Hopper博士设计了高级编程语言A-0,并在1952年构建了第一个编译器。
A-0语言和后来的变种并未广泛使用,而FORTRAN在1957年发布并主导了早期计算机编程。
FORTRAN允许程序员以更短的代码量编写程序,并通过编译器转换为机器代码。
1959年,行业、学术界和政府的计算机专家组成了一个联盟,开发了可在不同机器上使用的通用编程语言COBOL。
COBOL引入了“一次编写,到处运行”的概念,减少了对特定硬件的依赖。
高级编程语言的出现降低了进入计算机领域的门槛,使得非计算机专家也能将计算融入工作。
从1960年代到新千年,编程语言设计经历了黄金时代,与计算机硬件的进步同步发展。
许多编程语言如ALGOL、LISP、BASIC、Pascal、C、Smalltalk、C++、Objective-C、Perl、Python、Ruby和Java等相继出现。
编程语言的设计旨在利用新的抽象来简化编程的某些方面或利用新兴技术和平台。
许多编程语言和编译器只能在单一类型的计算机上运行,升级计算机通常需要重写所有代码。
编程语言的终极目标被认为是使用“纯英语”,使计算机能够理解并执行口头指令。
本集CrashCourse由CuriosityStream赞助,提供纪录片和非虚构作品的流媒体服务。
Transcripts
This episode is brought to you by CuriosityStream.
Hi, I’m Carrie Anne and welcome to CrashCourse Computer Science!
So far, for most of this series, we’ve focused on hardware -- the physical components of
computing -- things like: electricity and circuits, registers and RAM, ALUs and CPUs.
But programming at the hardware level is cumbersome and inflexible, so programmers wanted a more
versatile way to program computers - what you might call a “softer” medium.
That’s right, we’re going to talk about Software!
INTRO
In episode 8, we walked through a simple program for the CPU we designed.
The very first instruction to be executed, the one at memory address 0, was 0010 1110.
As we discussed, the first four bits of an instruction is the operation code, or OPCODE
for short.
On our hypothetical CPU, 0010 indicated a LOAD_A instruction -- which moves a value
from memory into Register A.
The second set of four bits defines the memory location, in this case, 1110, which is 14
in decimal.
So what these eight numbers really mean is “LOAD Address 14 into Register A”.
We’re just using two different languages.
You can think of it like English and Morse Code.
“Hello” and “.... . .-.. .-.. ---” mean the same thing -- hello! -- they’re just
encoded differently.
English and Morse Code also have different levels of complexity.
English has 26 different letters in its alphabet and way more possible sounds.
Morse only has dots and dashes.
But, they can convey the same information, and computer languages are similar.
As we've seen, computer hardware can only handle raw, binary instructions.
This is the “language” computer processors natively speak.
In fact, it’s the only language they’re able to speak.
It’s called Machine Language or Machine Code.
In the early days of computing, people had to write entire programs in machine code.
More specifically, they’d first write a high-level version of a program on paper,
in English, for example...
“retrieve the next sale from memory, then add this to the running total for the day,
week and year, then calculate any tax to be added”
...and so on.
An informal, high-level description of a program like this is called Pseudo-Code.
Then, when the program was all figured out on paper, they’d painstakingly expand and
translate it into binary machine code by hand, using things like opcode tables.
After the translation was complete, the program could be fed into the computer and run.
As you might imagine, people quickly got fed up with this process.
So, by the late 1940s and into the 50s, programmers had developed slightly higher-level languages
that were more human-readable.
Opcodes were given simple names, called mnemonics, which were followed by operands, to form instructions.
So instead of having to write instructions as a bunch of 1’s and 0’s, programmers
could write something like “LOAD_A 14”.
We used this mnemonic in Episode 8 because it’s so much easier to understand!
Of course, a CPU has no idea what “LOAD_A 14” is.
It doesn’t understand text-based language, only binary.
And so programmers came up with a clever trick.
They created reusable helper programs, in binary, that read in text-based instructions,
and assemble them into the corresponding binary instructions automatically.
This program is called -- you guessed it -- an Assembler.
It reads in a program written in an Assembly Language and converts it to native machine
code.
“LOAD_A 14” is one example of an assembly instruction.
Over time, Assemblers gained new features that made programming even easier.
One nifty feature is automatically figuring out JUMP addresses.
This was an example program I used in episode 8:Notice how our JUMP NEGATIVE instruction
jumps to address 5, and our regular JUMP goes to address 2.
The problem is, if we add more code to the beginning of this program, all of the addresses
would change.
That’s a huge pain if you ever want to update your program!
And so an assembler does away with raw jump addresses, and lets you insert little labels
that can be jumped to.
When this program is passed into the assembler, it does the work of figuring out all of the
jump addresses.
Now the programmer can focus more on programming and less on the underlying mechanics under
the hood enabling more sophisticated things to be built by hiding unnecessary complexity.
As we’ve done many times in this series, we’re once again moving up another level
of abstraction.
A NEW LEVEL OF ABSTRACTION!
However, even with nifty assembler features like auto-linking JUMPs to labels, Assembly
Languages are still a thin veneer over machine code.
In general, each assembly language instruction converts directly to a corresponding machine
instruction – a one-to-one mapping – so it’s inherently tied to the underlying hardware.
And the assembler still forces programmers to think about which registers and memory
locations they will use.
If you suddenly needed an extra value, you might have to change a lot of code to fit
it in.
Let’s go to the Thought Bubble.
This problem did not escape Dr. Grace Hopper.
As a US naval officer, she was one of the first programmers on the Harvard Mark 1 computer,
which we talked about in Episode 2.
This was a colossal, electro-mechanical beast completed in 1944 as part of the allied war effort.
Programs were stored and fed into the computer on punched paper tape.
By the way, as you can see, they “patched” some bugs in this program by literally putting
patches of paper over the holes on the punch tape.
The Mark 1’s instruction set was so primitive, there weren’t even JUMP instructions.
To create code that repeated the same operation multiple times, you’d tape the two ends
of the punched tape together, creating a physical loop.
In other words, programming the Mark 1 was kind of a nightmare!
After the war, Hopper continued to work at the forefront of computing.
To unleash the potential of computers, she designed a high-level programming language
called “Arithmetic Language Version 0”, or A-0 for short.
Assembly languages have direct, one-to-one mapping to machine instructions.
But, a single line of a high-level programming language might result in dozens of instructions
being executed by the CPU.
To perform this complex translation, Hopper built the first compiler in 1952.
This is a specialized program that transforms “source” code written in a programming
language into a low-level language, like assembly or the binary “machine code” that the
CPU can directly process.
Thanks, Thought Bubble.
So, despite the promise of easier programming, many people were skeptical of Hopper’s idea.
She once said, “I had a running compiler and nobody would touch it.
… they carefully told me, computers could only do arithmetic; they could not do programs.”
But the idea was a good one, and soon many efforts were underway to craft new programming
languages -- today there are hundreds!
Sadly, there are no surviving examples of A-0 code, so we’ll use Python, a modern
programming language, as an example.
Let’s say we want to add two numbers and save that value.
Remember, in assembly code, we had to fetch values from memory, deal with registers, and
other low-level details.
But this same program can be written in python like so:
Notice how there are no registers or memory locations to deal with -- the compiler takes
care of that stuff, abstracting away a lot of low-level and unnecessary complexity.
The programmer just creates abstractions for needed memory locations, known as variables,
and gives them names.
So now we can just take our two numbers, store them in variables we give names to -- in this
case, I picked a and b but those variables could be anything - and then add those together,
saving the result in c, another variable I created.
It might be that the compiler assigns Register A under the hood to store the value in a,
but I don’t need to know about it!
Out of sight, out of mind!
It was an important historical milestone, but A-0 and its later variants weren’t widely used.
FORTRAN, derived from "Formula Translation", was released by IBM a few years later, in
1957, and came to dominate early computer programming.
John Backus, the FORTRAN project director, said: "Much of my work has come from being
lazy.
I didn't like writing programs, and so ... I started work on a programming system to make
it easier to write programs."
You know, typical lazy person.
They’re always creating their own programming systems.
Anyway, on average, programs written in FORTRAN were 20 times shorter than equivalent handwritten
assembly code.
Then the FORTRAN Compiler would translate and expand that into native machine code.
The community was skeptical that the performance would be as good as hand written code, but
the fact that programmers could write more code more quickly, made it an easy choice
economically: trading a small increase in computation time for a significant decrease
in programmer time.
Of course, IBM was in the business of selling computers, and so initially, FORTRAN code
could only be compiled and run on IBM computers.
And most programing languages and compilers of the 1950s could only run on a single type
of computer.
So, if you upgraded your computer, you’d often have to re-write all the code too!
In response, computer experts from industry, academia and government formed a consortium
in 1959 -- the Committee on Data Systems Languages, advised by our friend Grace Hopper -- to guide
the development of a common programming language that could be used across different machines.
The result was the high-level, easy to use, Common Business-Oriented Language, or COBOL
for short.
To deal with different underlying hardware, each computing architecture needed its own
COBOL compiler.
But critically, these compilers could all accept the same COBOL source code, no matter
what computer it was run on.
This notion is called write once, run anywhere.
It’s true of most programming languages today, a benefit of moving away from assembly
and machine code, which is still CPU specific.
The biggest impact of all this was reducing computing’s barrier to entry.
Before high level programming languages existed, it was a realm exclusive to computer experts
and enthusiasts.
And it was often their full time profession.
But now, scientists, engineers, doctors, economists, teachers, and many others could incorporate
computation into their work .
Thanks to these languages, computing went from a cumbersome and esoteric discipline
to a general purpose and accessible tool.
At the same time, abstraction in programming allowed those computer experts – now “professional
programmers” – to create increasingly sophisticated programs, which would have taken
millions, tens of millions, or even more lines of assembly code.
Now, this history didn’t end in 1959.
In fact, a golden era in programming language design jump started, evolving in lockstep
with dramatic advances in computer hardware.
In the 1960s, we had languages like ALGOL, LISP and BASIC.
In the 70’s: Pascal, C and Smalltalk were released.
The 80s gave us C++, Objective-C, and Perl.
And the 90’s: python, ruby, and Java.
And the new millennium has seen the rise of Swift, C#, and Go - not to be confused with
Let it Go and Pokemon Go.
Anyway, some of these might sound familiar -- many are still around today.
It’s extremely likely that the web browser you’re using right now was written in C++
or Objective-C.
That list I just gave is the tip of the iceberg.
And languages with fancy, new features are proposed all the time.
Each new language attempts to leverage new and clever abstractions to make some aspect
of programming easier or more powerful, or take advantage of emerging technologies and
platforms, so that more people can do more amazing things, more quickly.
Many consider the holy grail of programming to be the use of “plain ol’ English”,
where you can literally just speak what you want the computer to do, it figures it out,
and executes it.
This kind of intelligent system is science fiction… for now.
And fans of 2001: A Space Odyssey may be okay with that.
Now that you know all about programming languages, we’re going to deep dive for the next couple
of episodes, and we’ll continue to build your understanding of how programming languages,
and the software they create, are used to do cool and unbelievable things.
See you next week.
Hey guys, this week’s episode was brought to you by CuriosityStream which is a streaming
service full of documentaries and nonfiction titles from some really great filmmakers,
including exclusive originals.
I just watched a great series called “Digits” hosted by our friend Derek Muller.
It’s all about the Internet - from its origins, to the proliferation of the Internet of Things,
to ethical, or white hat, hacking.
And it even includes some special guest appearances… like that John Green guy you keep mentioning
in the comments.
And Curiosity Stream offers unlimited access starting at $2.99 a month, and for you guys,
the first two months are free if you sign up at curiositystream.com/crashcourse
and use the promo code "crash course" during the sign-up process.
Browse More Related Video
![](https://i.ytimg.com/vi/rL8X2mlNHPM/hq720.jpg)
Intro to Algorithms: Crash Course Computer Science #13
![](https://i.ytimg.com/vi/nwDq4adJwzM/hq720.jpg)
Early Programming: Crash Course Computer Science #10
![](https://i.ytimg.com/vi/fOvTtapxa9c/hq720.jpg)
Natural Language Processing: Crash Course Computer Science #36
![](https://i.ytimg.com/vi/O753uuutqH8/hq720.jpg)
Software Engineering: Crash Course Computer Science #16
![](https://i.ytimg.com/vi/O5nskjZ_GoI/hq720.jpg)
Early Computing: Crash Course Computer Science #1
![](https://i.ytimg.com/vi/zltgXvg6r3k/hq720.jpg)
Instructions & Programs: Crash Course Computer Science #8
5.0 / 5 (0 votes)