#!/usr/bin/env python # coding: utf-8 # # Введение в программирование # В этой вводной лекции даются ответы на основные вопросы, связанные с процессом программирования: что такое программа, как она создается и выполняется, какие языки программмирования существуют и в чем они отличаются. С некоторыми понятиями из данного раздела вы, вероятно, уже знакомы, однако они приводятся здесь для того, чтобы изложение материала было последовательным и полным. Все примеры программного кода в этом курсе лекций приводятся на языке программирования Python, если не указано иное. # ## Содержание лекции # * [Что такое программа?](#Что-такое-программа?) # * [Языки программирования](#Языки-программирования) # * [Компиляция и интерпретация](#Компиляция-и-интерпретация) # * [Вопросы для самоконтроля](#Вопросы-для-самоконтроля) # ## Что такое программа? # **Программа** представляет собой последовательность инструкций, которые говорят вычислительной системе, что нужно сделать. Ответственность за выполнение программы лежит на процессоре (CPU), который считывает инструкции одну за другой из оперативной памяти и обрабатывает их. Инструкции, понятные непосредственно процессору, называются **машинными инструкциями** и представляют собой двоичный код строго определенного формата. Вся их совокупность называется **машинным кодом**, при этом, разные модели процессоров могут использовать разные наборы машинных инструкций, т.е. иметь отличающийся машинный код. В качестве примера приведем машинную инструкцию, складывающую два числа для процессора Intel Core i3/i5/i7: # ``` # 00000001 11000001 # ``` # Можно выделить два очевидных недостатка в программировании непосредственно в машинном коде: # * крайне длительный и затрудненный процесс программирования - машинные инструкции очень сложно запомнить, и они представляют собой лишь базовые примитивы (вроде простейших арифметических операций с парой чисел), которых требуется написать огромное количество для сколько-нибудь полезной программы # * программа, написанная в машинных кодах, может быть выполнена только на той модели процессора, для которой она разрабатывалась # Именно два этих фактора (в особенности первый) привели к созданию языков программирования. # ## Языки программирования # **Язык программирования** - это формальный, т.е. описываемый некоторыми правилами, язык, предназначенный для записи компьютерных программ. Все языки программирования можно разделить на **низкоуровневые**, в которых программы мало отличаются от программ в машинных кодах, и **высокоуровневые**, созданные для удобства разработки программ человеком. Несмотря на огромное количество языков программирования высокого уровня, низкоуровневые языки вроде Assembler до сих пор используются в областях, где требуется максимальное быстродействие, так как программы, написанные на них, можно вручную максимально оптимизировать под конкретную модель процессора. # Подобно обычным языкам, все языки программирования формулируют три составляющих, которые в совокупности определяют, *как* выглядит правильно составленная программа и *что* она делает: # * **Лексика** - определяет алфавит, из символов которого составляется программа. Как правило это английские буквы в нижнем и верхнем регистрах, цифры, знаки арифметических операций и препинания. # * **Синтаксис** - описывает допустимые комбинации символов алфавита, которые могут встречаться в правильно составленной программе. Например, `print(1+2)` является программой на языке Python (выводит сумму 1 и 2 на экран), а `print(1+)` нет, потому что согласно правилам этого языка после знака "+" в представленном выражении ожидается еще одно число. # * **Семантика** - определяет смысл конструкций языка программирования, то есть что они делают. Например, `1+2` в Python означает сумму 1 и 2, однако в другом языке программирования это же выражение может означать что-то другое. # Как упоминалось выше, основное назначение языков программирования - упростить процесс написания программ. Для этой цели языки программирования максимально приближены к естественным языкам, а это зачастую дает интуитивное понимание смысла программы. В подтверждение этих слов предлагаем вам догадаться самим, что делается в следующей программе (подсказка - после ее выполнения на экран будет выведено некоторое число, но нужно понять, какое именно): # ```python # some_list = [10, 5, 13] # max_value = 0 # # for value in some_list: # if value > max_value: # max_value = value # # print(max_value) # ``` # In[1]: get_ipython().run_cell_magic('HTML', '', '\nПоказать ответ\n
\n
Программа ищет в списке из трех элементов 10, 5 и 13 наибольший и выводит его на экран. Если вам не удалось ответить правильно, ничего страшного - через несколько лекций этот код покажется вам элементарным.
\n') # Бывают и такие языки программирования, в которых наоборот сделано все возможное, чтобы программа была нечитабельна, но создаются они исключительно ради эксперимента или шутки. Хорошим примером является язык программирования COW. Вот так выглядит программа, генерирующая [последовательность Фибоначчи](https://ru.wikipedia.org/wiki/%D0%A7%D0%B8%D1%81%D0%BB%D0%B0_%D0%A4%D0%B8%D0%B1%D0%BE%D0%BD%D0%B0%D1%87%D1%87%D0%B8), на этом языке: # # ``` # MoO moO MoO mOo MOO OOM MMM moO moO # MMM mOo mOo moO MMM mOo MMM moO moO # MOO MOo mOo MoO moO moo mOo mOo moo # ``` # Итак, мы получили представление о том, как выглядит программа, написанная на некотором языке программирования. Несмотря на большое различие между языками, у них есть одна общая черта: программа на любом из них представляет собой текст, следующий четко определенным правилам языка. Этот текст принято называть **исходным кодом** (или просто кодом) программы. # # Как упоминалось ранее, процессор может выполнить только программу, написанную в машинных кодах, поэтому возникает закономерный вопрос: как выполнить программу, написанную на некотором языке программирования, отличном от машинного кода. Ответ на него дается в следующем разделе. # ## Компиляция и интерпретация # Существует два основных подхода к выполнению программ: # * **Компиляция** - перевод программы с языка программирования в машинный код и последующее его выполнение. Компиляция выполняется специальной программой, называемой **компилятором**, которая получает на вход текстовый файл, написанный на некотором языке программирования, и создает из него исполняемый файл, содержащий машинные инструкции, который уже может быть выполнен процессором (в ОС Windows такие файлы имеют расширение _exe_). # * **Интерпретация** - процесс построчного разбора и выполнения исходного кода программы, выполняемый специальной программой, которая называется **интерпретатором**. Отличие от компиляции заключается в том, что при интерпретации исходный код переводится не в машинный, а в некоторый оптимизированный для быстрой обработки **байт-код**, который исполняется самим интерпретатором, выступающим в роли процессора для программы. При этом интерпретируемая программа выполняется сразу же по мере считывания интерпретатором строк ее исходного кода. # Как можно заметить, в обоих этих подходах существует этап преобразования программы с языка программирования в программу на некотором другом языке: в случае компиляции другим языком является машинный код, а в случае интерпретации байт-код. Процесс перевода программы, написаннной на одном языке, в программу на другом языке называется **трансляцией**. Специальная программа, выполняющая трансляцию называется **транслятором**. # Каждый из двух представленных подходов к выполнению программ имеет свои преимущества и недостатки. Главный плюс компиляции в том, что ее можно выполнить один раз, получить исполняемый файл, который можно бесконечное количество раз запускать на процессоре без дополнительной обработки. При интерпретации на каждом запуске программы выполняется ее разбор интерпретатором и трансляция в байт-код, что приводит в общем случае к более медленной работе по сравнению с аналогичной, но скомпилированной программой. С другой стороны, процесс компиляции может занимать очень много времени (исчисляется часами) и должен выполняться при малейшем изменении в исходном коде программы, а интерпретируемая программа запускается мгновенно. Кроме того, интерпретатор может обеспечивать дополнительный уровень безопасности для системы в целом: отслеживать некорректные операции программы, следить за тем, чтобы она не расходовала излишне оперативную память и другое. Обобщенно можно сказать так: компиляция создает более быстрые программы, но требует больше усилий от разработчика, в отличие от интерпретации. # ![Выполнение программы](./images/01/program-execution.png) # В соответствии с подходом, используемым для выполнения программ, различают компилируемые и интерпретируемые языки программирования. К числу наиболее известных компилируемых языков относятся C, C++, Objective-C, Go и другие. Python, а также Java, PHP, Perl и другие относятся к интерпретируемым языкам. # ## Вопросы для самоконтроля # 1. Что такое программа? Какой компонент компьютера выполняет ее? Как называются инструкции, понятные этому компоненту? # 2. Как три аспекта обязательно нужно описать, если вы захотите создать свой собственный язык программирования? В чем заключается их суть? # 3. В чем схожесть и различие компиляции и интерпретации? # 4. Представьте, что нужно написать программу, обрабатывающую все финансовые транзакции крупного банка. Какой язык программирования предпочтительнее для выполнения этой задачи: компилируемый или интерпретируемый? Почему? # # - - - # [Содержание](00_Overview.ipynb#Содержание) | # [Следующая: Установка Python](02_Installing_Python.ipynb)