第 10 集 · B1 · 7 分钟

C 语言 · 第10集 · 程序是怎么编译的

从 Hello World、循环、递归讲到汉诺塔和动态规划,句子短,适合跟读。 开头:编译器,用于将源代码转换为

C 语言 · 第10集 · 程序是怎么编译的

中俄字幕

  1. компилятор, чтобы превратить исходный текст в

    编译器,用于将源代码转换为

  2. исполняемый файл.

    可执行文件。

  3. три основных этапа.

    三个主要阶段。

  4. Первый этап по- английски называется preprocessing.

    第一阶段英文称为预处理(preprocessing)。

  5. И выполняется он препроцессором компилятора.

    由编译器的预处理器执行。

  6. Состоит этот Собственно, процесс, препроцесс, да, или, по- русски говоря,

    实际上,这个过程就是预处理,或者说,用中文讲,

  7. предобработка, хотя в среде программистов устоялось

    预处理。不过在程序员圈子里,已普遍使用

  8. не совсем русское слово препроцессинг, да, здесь инговое окончание явно не русское

    一个并非完全俄语的词——‘预处理’(preprocessing),是的,这里的英文后缀显然不是俄语的,

  9. слово, но именно оно чаще всего используется, да.

    但这个词却最常被使用。

  10. Так вот, смысл вот этого процесса в том, чтобы удалить комментарии.

    该过程的核心目的是删除注释。

  11. раз, второе выполнить текстовые замены.

    第一步,执行文本替换。

  12. То есть есть некие макросы, да, вот этот кусок надо заменить на вот этот вот.

    也就是说,存在一些宏——是的,这部分内容需替换成另一部分。

  13. И оказывается, что это удобно.

    结果发现,这种方式非常方便。

  14. Ну и есть еще всякие включения текста, то есть мы этот текст либо включаем, либо не

    此外还有各种文本包含机制,即我们选择是否包含该文本。

  15. включаем. Ну, например, условное, да,

    例如条件包含,对吧?

  16. при некоторых обстоятельствах какой- то кусок исходного текста не должен попадать,

    在某些情况下,源代码的某一部分不应被处理。

  17. собственно, на обработку.

    它不应进入后续处理流程。

  18. Он не должен включаться в итоговом результате, получающийся исполняемый файл.

    它不应出现在最终生成的可执行文件中。

  19. Вот, это тоже выполняется препроцессором.

    这些操作均由预处理器完成。

  20. Понятно? Условная компиляция.

    明白了吗?这就是条件编译。

  21. И еще. Важный момент— это подключение библиотек.

    另外,一个重要环节是链接库。

  22. Оно в языке C устроено так, что требуется прямо явным образом включить кусок текста

    在C语言中,这一过程要求显式地将一段文本内容包含到您的源文件中。

  23. в ваш файл. Мы это с вами увидим.

    我们稍后会看到这一点。

  24. Второй этап компиляции— это собственно compilation или компиляция.

    编译的第二阶段是真正的编译(compilation)。

  25. Я использую еще одно слово— трансляция, translation.

    我还使用另一个词——翻译(translation)。

  26. То есть непосредственно перевод с языка высокого уровня на язык машинных кодов.

    即直接将高级语言代码转换为机器码。

  27. Это происходит именно вот в этот момент.

    这一步就发生在此刻。

  28. После этой обработки.

    经过此处理之后。

  29. появляется объектный файл.

    就会生成目标文件。

  30. Кстати говоря, вот здесь вот, хотя я нарисовал файл, да, на самом деле никакого

    顺便提一句,这里我虽然画了一个文件,但实际上并不存在这样一个文件。

  31. файла нету. Да, файл обычно не создается.

    文件不存在。是的,该文件通常不会被创建。

  32. можем его создать, можем увидеть результат препроцессинга.

    我们可以创建它,也可以查看预处理的结果。

  33. Но вот этот вот результат, он всегда есть и валяется там же рядышком в папочке

    但这个结果始终存在,通常就放在您项目文件夹的同一目录下。

  34. вашего проекта обычно.

    在您的项目文件夹中。

  35. И многие начинающие программисты не понимают, откуда он берется, зачем он вообще

    许多初学程序员并不理解它从何而来,以及它存在的意义。

  36. нужен. Файл. O- это объектный файл.

    这个文件就是目标文件(.o 文件)。

  37. Он уже на языке низкого уровня, на языке машинных кодов.

    它已经是低级语言形式,即机器码语言。

  38. Уже не человекочитаем, но

    已经不可读了,但

  39. все- таки в нем еще остается некоторая символная информация.

    其中仍保留了一些符号信息。

  40. в частности названия функций.

    特别是函数名称。

  41. Название функции main, например, да, или какая то еще информация там может

    例如,主函数的名称,是的,或者其中可能还有其他信息

  42. сохраняться. а вот дальше происходит процесс линкинг, линковка или сборка.

    会被保存下来。接下来则进行链接(linking)或链接(linkage)过程。

  43. Почему этот процесс важен?

    为什么这个过程很重要?

  44. Потому что исходный текст, он обычно не один.

    因为源代码通常不止一个文件。

  45. Как минимум, вам нужна какая- нибудь стандартная библиотека.

    至少,你需要某种标准库。

  46. И с этой библиотекой вам надо связаться, вам нужно ее прикомпоновать.

    你必须将程序与该库关联起来,即需要将其链接进来。

  47. Вот есть русское слово.

    这里有一个俄语词:

  48. это компоновка, компоновка.

    即‘链接’(linking)或‘连接’(linkage)。

  49. Есть еще одно русское слово сборка.

    还有一个俄语词:‘构建’(build)。

  50. Оно тоже понятное и логичное.

    这个词同样清晰且合乎逻辑。

  51. Сборка из нескольких единиц трансляции.

    由多个翻译单元组成的构建。

  52. То есть у нас есть несколько объектных файлов.

    也就是说,我们有多个目标文件。

  53. из которых мы, ну не мы, а компилятор, точнее даже на самом деле часть компилятора,

    其中——嗯,不是我们,而是编译器,更准确地说,是编译器的一部分——

  54. которая называется линковщик или компоновщик, так вот именно он раз и собирает

    称为链接器(或连接器)的这部分,正是它来完成链接工作,

  55. исполняемый файл.

    生成可执行文件。

  56. Вот. Но чаще всего в среде программистов этот процесс называется в

    是的。但在程序员圈子中,这一过程通常按英文术语“linking”称为“链接”(linking),

  57. соответствии с английским термином linking, линковка,

    即“链接”(linking),

  58. хотя слово не русское.

    尽管这个词并非俄语原生词汇。

  59. Давайте посмотрим, как

    让我们看看

  60. эти процессы выполняются компилятором GCC.

    GCC 编译器如何执行这些过程。

  61. Ну, совсем кратко про компилятор.

    好吧,简单介绍一下编译器。

  62. Компилятор GCC- это один из.

    GCC 编译器是其中一种。

  63. наверное, самых популярных компиляторов в мире, не единственный, но он является

    也许是全球最流行的编译器之一,虽非唯一,但却是主流。

  64. основным для операционных систем, юникс подобных большинства, линукса и многих

    它主要用于大多数类 Unix 操作系统,如 Linux 及许多其他系统。

  65. других. Итак, давайте с вами включимся и посмотрим на наш.

    好了,我们一起来启动并查看我们的程序。

  66. Hello world. То есть напоминаемый на.

    Hello World 程序,也就是我们之前提到的。

  67. Сейчас я открою отдельное окошко Build Log.

    现在我将单独打开一个“构建日志”窗口。

  68. Дело в том, что мы смотрели пока что Build Messages, и тут смотрели просто ошибки,

    因为我们之前只查看了“构建消息”,那里仅显示出现的错误。

  69. появляющиеся. Build Log- это

    而‘构建日志’则是一个日志,相当于一份简短的记录,即构建过程的日志。

  70. лог, это как бы история маленькая, да, лог сборки.

    构建日志就是一份日志,相当于一份简短的记录,即构建过程的日志。

  71. что собственно происходило.

    实际上发生了什么。

  72. И мы можем увидеть, что здесь происходило при сборке две вещи.

    我们可以看到,在构建过程中发生了两件事。

  73. да, раз и два.

    对,一是和二是。

  74. Кстати, мы можем увидеть ту самую опцию warnings all wall, да, читается как стена

    顺便说一下,我们可以看到那个叫‘warnings all’(-Wall)的选项,是的,读作‘wall’(墙)。

  75. практически, да, но warnings all, все ворнинги, да.

    差不多吧,但‘warnings all’意思是启用所有警告,对。

  76. которая была, да, и видим какие- то опции компиляции- c- o.

    该选项确实存在,对,还能看到一些编译选项,比如‘-c -o’。

  77. Видим запуск, собственно, компилятора, запуск какого- то другого еще, да, ну под

    我们看到实际启动了编译器,还启动了另一个程序,嗯,具体来说……

  78. Windows у меня стоит MinGW.

    我在 Windows 上安装的是 MinGW。

  79. ну и собственно указание вот исходный файл, да, вот мы видим появляется здесь

    然后就是指定源文件,对,我们在这里看到……

  80. объектный файл.

    目标文件(object file)出现了。

  81. Давайте сделаем вот что.

    我们来这样做。

  82. Давайте запустим все эти процессы вручную.

    让我们手动启动所有这些进程。

  83. Единственное, что я буду пользоваться сокращенным названием компилятора, и я не буду

    我唯一会使用编译器的缩写名称,而不会

  84. звать g++, я буду все время сейчас звать gcc.

    调用 g++,而会一直调用 gcc。

  85. exe. Итак, для этого мне понадобится

    exe。因此,我需要

  86. интерпретатор командной строки.

    命令行解释器。

  87. Я его вызову просто windows+ r, cmd, и вот у

    我只需按 Win+R,输入 cmd 即可调出它,看,

  88. меня уже интерпретатор командной строки.

    我的命令行解释器已经打开了。

  89. Я могу перейти в свою папочку проекта.

    我可以进入我的项目文件夹。

  90. Вот у меня здесь лежит файлик hello world.

    这里就放着我的 hello world 文件。

  91. C. Что мне нужно сделать для того, чтобы его скомпилировать?

    C. 我需要做什么才能编译它?

  92. Значит, во- первых, мне нужно доступиться к компилятору.

    首先,我需要访问编译器。

  93. Если вы наберете там gcc.

    如果你在那里输入 gcc。

  94. exe или даже полное наименование там mingw32- gcc,

    .exe,甚至完整名称 mingw32-gcc,

  95. это вам не поможет, потому что просто потому, что вы как

    这也没用,因为根本

  96. бы не дотянетесь до компилятора.

    就无法访问到编译器。

  97. Он лежит где- то там, и командная строка про него не знает.

    它被放在某个位置,而命令行并不知道它的存在。

  98. Надо сказать, что в Linux'е в этом смысле обычно пути в командной строке настроены

    需要说明的是,在 Linux 系统中,命令行的路径通常已配置好,

  99. так, что она знает, где лежит компилятор.

    因此命令行能知道编译器的位置。

  100. Поэтому, чтобы туда дотянуться, нам надо в первую очередь найти наш компилятор.

    因此,要访问编译器,我们首先得找到它。

  101. Я это сделаю следующим образом.

    我将按以下方式操作。

  102. открою компилятор Code Blocks, посмотрю в его свойства, где он собственно находится,

    打开 Code::Blocks 编译器,查看其属性,确认它实际安装的位置,

  103. открою.

    然后打开。

来源:Тимофей Хирьянов · CC BY 3.0

同系列