АЙТИШНЫЙ САЙТ ПЕТРА СЕМИЛЕТОВА

ПЕТР СЕМИЛЕТОВ

ПРОСТО С++: УРОК 1

О программировании вообще. Машинные коды. Язык ассемблера. Языки выского уровня. Что нам понадобится для практики? Компиляторы.

Язык программирования С++ - им пугают новичков, дескать, очень сложный в изучении. Так ли страшен черт, как его малюют? Стоит ли начинать учить программирования с чего-то другого, вроде Джавы? Мне кажется, не стоит. Это как выбор - стать поваром или размачивать себе сухую вермишель из пакетиков. C++ - универсальный язык для написания высокопроизводительных программ, от игровых движков до операционных систем и графических редакторов. Ткните пальцем в большую и популярную программу, и окажется, что она написана на С++. Google Chrome, Adobe Photoshop, браузер Opera, старый добрый Doom.

Итак, перед вами выбор - научиться размачивать вермишель и добавлять в нее приправу из пакетика, или стать поваром. Это два разных подхода.

Если выбираете второе, читайте дальше.

Безразлично, помните ли вы что-то о программировании из школьной информатики. Начнем с написания самых простых программ, а сложные вы напишите потом сами, если захотите.

Что нам понадобится? Покамест всего две программы. Одна из них это простой текстовый редактор, который открывает и сохраняет обычные, не доковские, текстовые файлы. Для системы Windows подойдет даже привычный Блокнот.

В текстовом редакторе мы будем писать текст - исходный код - программы. Исходный код - неправильное, но прижившееся выражение. Ведь программа на С++ это не код, а особым образом составленные предложения на сильно сокращенном английском языке. По сути, все языки программирования высокого уровня - а есть еще низкого - имеют словарный запас, основанный на английском, только он сокращен до необходимого минимума, чтобы на нем можно было записывать логические рассуждения. Словарь из такого необходимого минимума называется ключевыми словами.

Программирование сродни кулинарным рецептам. Если вода в кастрюле закипела, бросить туда макароны. Программирование это образ мышления, где все подчинено логике, и посредством логики определяется поведение и устройство вещей. Если введен правильный пин-код, то выдать деньги, иначе выплюнуть кредитную карту. Если повернуть руль велосипеда, движение велика отклоняется в сторону поворота руля. Так устроен мир. Физик подмечает законы, программист их пишет.

Еще программирование - это вычисления, работа с числами. На самом низком уровне - всего лишь сложение, вычитание, умножение, деление, а также сравнение. Если сумка весит тонну, человек не может ее поднять. А если килограмм, поднимет и не крякнет. В условной программе это выглядело бы так

Человек поднимает сумку
Проверить, весит ли сумка больше или равно 1000 килограммов
Если да, ничего не делать
Иначе, человек берет сумку и идет по своим делам

Но компьютер не понимает таких слов, ему всё нужно разжевать. Языки высокого уровня занимаются таким разжевыванием именно на высоком уровне, то есть вы действуете почти в рамках человеческого языка, используя ключевые слова языка программирования и вводя свои новые.

Но прикол в том, что компьютер не понимает то, что вы хотите ему сказать на языке программирования.

Мозг компьютера - процессор - очень быстр, но очень туп. Он может сложить два числа за миллиардные доли секунды. Но у него есть ограничение в мышлении.

Попросите человека - сложи два плюс два и скажи результат. Ничего трудного, верно?

Процессор не понимает таких слов. Он понимает числовые коды - команды. И действует согласно командам. Каждая команда имеет свой номер. Это как если бы человек знал, что когда ему скажут - раз! надо ступить левой ногой, а скажут два - правой! и тогда если мы будем говорить человеку раз-два, раз-два, человек будет шагать, выполняя эти нехитрые команды.

Каждая команда для процессора имеет свой номер. Такие пронумерованные команды процессора называют опкодами (opcodes) - кодами операций. Разные процессоры могут в чем-то совпадать основными опкодами, а в чем-то отличаться. Процессоры одной линейки, с каждым поколением, обзаводятся новыми опкодами, получая тем самым новые возможности. Соображаловка расширяется.

Помимо этого, у процессора есть особые ячейки памяти - регистры. Представьте себе открытые ячейки в отделе хранения в супермаркете. Они, как и регистры процессора, пронумерованы.

И если мы хотим попросить процессор, как человека, сложить два плюс два, мы кладем первую двойку в одну ячейку-регистр, вторую в другой регистр, и подаем опкод - команду с определенным номером. За этой командой, в нашем случае, закреплено действие - сложить числа, которые лежат в таких-то регистрах-ячейках, и положить результат в первую ячейку.

Это не язык С++! Это называется машинные коды! Самый низкий уровень доступа к аппаратной части. Непосредственно на нем очень, очень редко пишут программы, ибо это весьма трудоемко. Это как вместо того, чтобы попросить дать вам стакан воды, вы бы начали перечислять все атомы, из которых состоит и стакан, и вода.

Существует такой язык программирования, именуемый язык ассемблера, в просторечии просто ассемблер (assebmler, asm), хотя есть еще одноименная программа. Ассемблер немного приближает машинные коды к человеку, предоставляя вместо номеров команд - собственно кодов - осмысленные слова, целые или сокращенные, на английском языке. На ассемблере мы всё еще вынуждены возиться с регистрами, но они тоже получают названия, а не предстают перед нами абстрактными номерами.

Вот пример кусочка программы на упрощенном ассемблере:

mov 2, ax 
mov 2, dx
add dx, ax 

Команда mov - поместить, можно сказать задвинуть куда-либо, mov сокращение от move. В первой строке мы помещаем, задвигаем число 2 в регистр под названием ax, во второй строке помещаем 2 в регистр dx, и командой add (что переводится как сложить) складываем содержимое регистров ax и dx, и получаем результат в регистре ax.

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

В нашем примере команда mov берет число из первого операнда и кладет его в регистр, обозначенный во втором операнде. Тут есть одна тонкость.

У языка ассемблера есть много диалектов. Для процессоров архитектуры X86 - привычные нам персональные компьютеры - популярны два диалекта. Первый, на котором и написан пример, разработан компанией AT&T. Он принят в системе Linux. В Windows шире используется другой диалект ассемблера, разработанный корпорацией Intel.

Основное отличие - порядок операндов. Поясню на примере. Если в At&T у нас

mov что кладем, куда кладем

то в Интел:

mov куда кладем, что кладем

На диалекте At&T Сидоров шел в деревню

На диалекте Интел В деревню шел Сидоров

Чтобы сложить 2 + 2 на ассемблере, мы написали программу из трех строк, вручную помещая числа в ячейки памяти - в регистры. А на языке высокого уровня вроде Паскаль или С++, нам достаточно просто написать: 2+2

Пример:

   sum = 2+2;

Здесь sum это название переменной. sum в переводе значит сумма. Вообще мы можем давать переменным произвольные имена. Так сложилось, что принято делать это на английском языке.

Знак равенства “=” - это операция присваивания. За ней следуют операнды 2 и 2, между которыми плюс - тоже операция, операция сложения. Наконец, завершает предложение точка с запятой. Так нужно по правилам языка С++.

Переменная это имя, при помощи которого вы можете обращаться к ячейке. Поименованный ящик. Что лежит в ящике sum? А то, что мы туда положим. Чтобы положить, используем знак равенства. А что положить? То, что следует после этого знака. В нашем случае - 2 плюс 2. Сумма будет вычислена и результат помещен в переменную sum.

Даже на таком простом примере, как сложение двух чисел, преимущества языков высокого уровня налицо. Что тогда говорить о сложных программах, где, как вы понимаете, действие не ограничивается два плюс два.

Но процессор не понимает язык высокого уровня, ему машинные коды подавай.

Поэтому программисты придумали особый класс программ - компиляторы. Компилятор берет текст программы, написанный на языке высокого уровня, и переводит его на язык низкого уровня - на ассемблер, беря на себя рутинную нудную работу по разложению на молекулы. Затем компилятор вызывает программу-ассемблер, которая переводит уже с языка ассемблера в машинные коды, разлагая молекулы на атомы. Упрощенно говоря, когда мы скармливаем ассемблеру программу на языке ассемблера, то получаем на выходе исполняемый файл.

Прослойка в виде ассемблера позволяет писать программы на языке выского уровня и переводить их на опкоды процессоров разных архитектур. В восьмидесятые годы, когда разработчики игр выпускали хиты для разных аппаратных платформ, им приходилось нелегко. Например, Принц Персии в версии для NES (Денди) и в версии для ПК под системой MS DOS был фактически переписан с нуля - конечно, при общей графике. Потому, что опкоды у процессоров в NES и ПК разные.

Я предполагаю, что вам уже не терпится вооружиться программой-компилятором и начать программировать. Ведь у нас уже есть текстовый редактор, в котором вы будете писать программы, дело, кажется, осталось за малым - обзавестись компилятором и научиться с ним работать. Но об этом - на следующем уроке.

Поддержать курс:

Навигация:

Оглавление

Следующий урок