![]() | ![]() | ![]() | |||||||||||
![]() |
|
||||||||||||
![]() | ![]() | ![]() | |||||||||||||||
![]() |
|
||||||||||||||||

Техническая поддержка
ONLINE
![]() | ![]() | ![]() | |||||||||||||||||
![]() |
|
||||||||||||||||||
Лекция 2. Основные команды в терминале. Компиляция программ
ruticker 05.03.2025 11:07:44 Текст распознан YouScriptor с канала Мещерин Илья
распознано с видео на ютубе сервисом YouScriptor.com, читайте дальше по ссылке Лекция 2. Основные команды в терминале. Компиляция программ
Я ещё должен нам рассказать про литералы и литеральные суффиксы. Вот смотрите, есть такое понятие **Литерал**. Что такое Литерал? Это последовательность символов в коде программы, которая обозначает некоторые конкретное значение какого-то типа. Например, **пять** — это литерал. А, нужно, черный маркер, наверное, достать. Да, вот я говорил о том, что такое литерал. Вот, например, **пятерка** — это литерал, или **0**, не знаю, **2** — это литерал, или **"A B C"** в кавычках двойных — это литерал, или вот, например, **'A'** в одинарных кавычках — это литерал. Для каждого литерала захардкожено, к какому типу он относится. Вот это **int**, вот это **double**, или **террасплавающей точки** по умолчанию относится к типу **double**. Вот это тип **char**. Вот и еще существует понятие литеральных суффиксов. Вы можете попросить, чтобы литерал поменял свой тип. Например, если вы хотите, чтобы литерал с плавающей точкой у вас считался **float**, а не **double**, вы можете написать **0.2F** в конце. Вот это **F** — это литеральный суффикс, так называемый. По умолчанию, если вы пишете **0.2**, это считается **double**, а если вы хотите, чтобы она считалась **float**, то вы пишите **0.2F**. Зачем может быть нужно явно просить, чтобы тип литерала стал чуть другим? Ну, например, если вы **float** обрабатываете по-разному. Если у вас есть функция для **float**, которая принимает **float**, и функция с таким же названием, которая принимает **double**, то вот вы ее вызовете от **0.2** — вы попадете в версию для **double**, а если вызовете **0.2F** — вы попадете в версию для **float**. Понятно? То же самое есть еще полезный литерал. Например, есть такой, который означает... Зачем может быть надо просить, например, чтобы переполнение работало так, как вы хотите? Вот, например, если вы сложите два очень больших **int** и произойдет переполнение, то это формально неопределенное поведение. А если вы сложите два больших **unsigned int** и произойдет переполнение, то это определенное поведение: **unsigned** переполняются регламентированно, как мы просто по модулю берется, вот, а знаковые переполняются — у беда. Вот существует также неявные преобразования типов. То есть, если вы написали **int** и проинициализировали ее каким-нибудь значением, которое не тип **int** имеет, ну, например, тем же, проинициализировали, произойдет неявное преобразование. Некоторые неявные преобразования безопасны, а некоторые опасные. Вот, например, преобразование потенциально опасно, потому что некоторые значения имеют хранить, которые обычно не умеет, и теоретически преобразование может привести к переполнению, которое приведет к неприятностям. Поэтому компилятор вам может иногда в орден кинуть: "Вы тут неявно преобразовываете". Вот какие преобразования безопасны? Вы можете безопасно преобразовывать **char** в **int**, **int** в **long long**, **long long** в **long long**. То есть преобразование, которое повышает диапазон, они еще называются **promotion**. Они называются **integer promotions** — это преобразование, которое повышает вид **int** до более широкого. Вот они безопасные, их можно безопасно делать, они называются **integer promotions**, и в общем-то они неявно делают. Если вы складываете два **int** разной ширины, если вы складываете **char** с **int**, то вы получите **int**. **Char** повысится до **int**. Если вы складываете **int** с **long long**, то **int** повысится до **long long** и вернется вам **long long**. То же самое есть **floating point promotion** — это когда вы **float** повышаете до **double**. Понятно, что все, что представимо **float**, представимо и **double**. Поэтому, если вы делаете действия над **float** и **double**, то получается в результате **double**. А если вы делаете действия с **int**, то в результате получается **long double**. Понятно? А также есть неявное преобразование между **bool** и **int**. Про это мы уже говорили. Ну, между **bool** и целочисленными другими типами это мы уже обсуждали. Сегодня они тоже неявно делаются. Если вдруг в каком-то месте ожидается **bool**, вы передадите тип, то произойдет неявная конверсия. И есть преобразование между целочисленными и типами с плавающей точкой в одну сторону. Ну, как я уже говорил, если вы из **int** конвертируетесь в **double**, ну, или если вы там конвертируетесь из каких-то других целочисленных типов в плавающую точку, так что вы попадаете в более широкое множество, то это безопасное преобразование. Это все неявные допустимые преобразования. А вот если в обратную сторону конвертируетесь, вы теряете точность. Можно сконвертировать неявно **double** в **int** или **float**, ну, или **long long**, как хотите, вы потеряете точность в том смысле, что дробная часть отбросится у вас. Если там, например, вы **4.9**, если вы напишете **X = 4.9**, будет **4**. Вот, потому что, понятно, отбросить дробную часть. По-хорошему, вообще компилятор обычно кидает предупреждение. Если там компилятор хорошо настроен на разные максимальные предупреждения, то он кидает предупреждение в случае, когда у вас неявные конверсии происходят, которые вы, возможно, не замечаете. И чтобы вы понимали, что неявные конверсии — это зло. Вообще это зло. Я вам приведу один пример и одну цитату. Значит, пример такой: вот как вы думаете, что происходит, если вы складываете **int** с **unsigned int**? Какой тип у результата? **unsigned int**? Неправильно! **int**. В частности, если вы делаете так, то получается **4 миллиарда с лишним**. Вот, да, если написать **-1**, это уже будет **4 миллиарда**, потому что, понятно. Но если у вас есть какой-то маленький **int**, и вы из него вычитаете **unsigned**, или наоборот, у вас есть маленький **unsigned int**, как, например, **vector.size**, и вы из него вычитаете **int**, вот у вас есть размер вектора **5**, и вы решили обойти все элементы вектора, кроме последних **10**. В **-10** вы из... То есть вы читаете, получаете **unsigned** и **4 миллиарда**. В итоге цикл до **4 миллиардов**. Здравствуйте! Вот эта история однажды выстрела. Я помню, когда я в своей жизни запомнил, что сложение **int** с **unsigned** — это не просто **int**, это я уже работал в **Яндекс.Такси** в то время. Да, не это было хобби, вообще-то я был бизнесменом, но вообще-то я преподом работал. **Яндекс.Такси** — это было хобби, да, а я разработчиком работал в **Яндекс.Такси**, конечно, и писал на **плюсах**. И там однажды в каком-то коде нужно было вычислять время в пути водителя, и там нужно было делать какие-то поправки. Вот, что там, на сколько секунд быстрее он приедет. И что вы думаете, там был значит **unsigned int**, только секунду доберется, и вот из него вычитался, что в некоторых ситуациях приводило к тому, что он доберется за **4 миллиарда секунд**. Казалось бы, время в пути водителя — это знак знаков. Нет, беззнаковый вычитаем из него что? Ну, наверное, **int**, потому что поправка может быть как положительной, так и отрицательной. Все **4 миллиарда** получилось. Вот, ну был такой баг. Вот я вам обещал еще цитату. Тут как-то несколько лет назад было интервью с создателем, где-то очередное. Его спросили: "Если бы вы делали язык **C++** заново, вообще все с нуля начинали, то что бы вы сделали по-другому?" Он сказал, задумался, сказал: "Трудно. Значит, просто, наверное, он сказал, я бы запретил неявные конверсии между примитивными типами, потому что тогда никто не думал, насколько много бед они в современном мире принесут". Короче, избегайте конверсии. Явные конверсии — это плохо. Ну что еще вам сказать? Еще, наверное, он вот что скажу. Вот вы знали, что можно целые числа записывать в шестнадцатеричной системе счисления? А можно и восьмеричной. Вот целые числа можно записывать в шестнадцатеричной системе. Для этого нужно начать с префикса **0x**. Ноликс, и дальше, например, написать **FF** — это будет значительный литерал, который означает **255**. Это просто вот литерал, начинающийся с ноликса — это целочисленный литерал, записанный в системе. Если вы записываете число с нуля, то это воспринимается как восьмеричная система. Например, **0 1 2 3** — это вовсе не **123**, как можно было бы подумать, а это **64 плюс 16 плюс 3** — **83**. То есть если вы так напишите, литералы с нуля считаются записанными в восьмеричной системе. В двоичной системе я не помню, можно ли записывать **0b**. По-моему, начиная с какого-то стандарта все-таки можно. Да, **0b101**. В общем, вот как будто. Да, мне казалось, что это не работает. Год назад тоже спорили, я так и не помню, к чему пришли. Ну, в общем, мне лень проверять. Будем считать, что нет. Давайте, наконец, что-нибудь на ноуте попишем. Ну да, начиная с какой-то версии вроде оно как бы работает, но вот как-то... А, да, кто не знал, но вы услышали, начиная с **14 плюсов** можно, если записываете длинное число, использовать апостроф, или как правильно говорить, апостроф для разделения разрядов. То есть можно писать не **1 миллион**, а **1'000'000**. Это удобно для чтения. Так, господа, добро пожаловать в командную строку **Linux**. Как вы, наверное, знаете, мы все презираем **Windows** здесь и поэтому рекомендуем вам перейти на **Linux** или, в крайнем случае, на **Mac OS**. В ближайшее время, ну, если серьезно, то с **Виндой** не то чтобы вам будет совсем плохо на первом курсе. Давайте так, у кого **Винда**, а у кого там **Linux**? Ну или **Linux** что-то, **Убунта**? А у кого **macOS**? Окей. Ну вот, у кого **Убунта** или **Linux**, что-то семейство **Linux** — вы молодцы, вам будет удобно и хорошо. Все то, что я буду показывать, будет у вас один в один работать. Да, есть **WSL**, сейчас про него скажу. У кого **macOS**, у кого **Винда** — вам не то чтобы будет прям совсем плохо, но я рекомендую установить **Linux**. Не потому что вы как бы не справитесь, курс сдать без него, а потому что просто чем раньше вы к нему сами привыкните, тем лучше для вас же в будущем. На втором курсе вам все равно придется очень плотно сидеть под **Linux**, потому что когда у вас на втором курсе будет операционная система, вы будете писать именно под **Linux**. Под **Виндой** ничего это невозможно сделать и удобно. Если вы к началу второго курса уже будете, ну или каким-то другим **Linux** пользоваться свободно, вот, просто для вас же самих это будет полезно. Ну и когда вы придете даже работать, если вы устроитесь в какую-нибудь желтую или, или там, я не знаю, синюю компанию, вот вы, ну, может и в зеленую, то вы, скорее всего, обнаружите, что там все равно все под **Linux**, и мало кто **Виндой** пользуется. И да, этот человек на работе, ему приходится сидеть под **Виндой**, но не будем об этом. Вот, короче, вам же будет удобнее лучше привыкнуть пораньше. Вот, я буду показывать примеры все под **Убунтой**. У меня **Убунта 20** или **21**, не помню. Если вы находитесь в странной ситуации, потому что, с одной стороны, почти все у вас будет работать, и вам не стоит ставить, тем более я не уверен, что можно сделать на **MacBook**, с другой стороны, некоторые вещи у вас будут работать не совсем так, как у меня, и возможно, это будет вызывать некоторую особенную боль. Она вроде почти так, но ввиду особенности операционки не совсем так. Вам приходится разбираться, что же именно работает, иначе местами это может вызывать некоторые небольшие боли, но не такие большие, как под **Виндой**. Хорошо, сейчас мы переходим к параграфу **1.1**, который пропустили тогда, и параграф называется **знакомство с компилятором и первая программа**. Вот, но на самом деле это будет даже знакомство не столько с компилятором, сколько с терминалом. Вот я сейчас покажу некоторые базовые команды для работы в терминале. Ну, потому что буду **Убунты**, и вообще в мире программирования принято много чего делать из командной строки. Вот и такой джентльменский набор начинающего разработчика входит знание некоторых базовых команд **Linux**, которая позволяет вам какие-то базовые операции делать над файлами. Вот сейчас я нахожусь в командной строке. Вот это название моего компьютера, вот это то, как меня зовут, то есть я на таком-то компьютере, да, находясь в такой-то директории, говорю следующее, и вот здесь могу вводить команды. А самая, наверное, распространенная команда — это перейти в другую директорию, и она записывается **cd** от слов **change directory**. Вот я говорю **cd** и говорю, куда. Ну, я могу назвать директорию, в которой я хочу перейти, а могу, например, назвать мнемонику для какой-то специальной директории. Вот у меня есть всегда из любой директории две точки, означает подняться на директорию вверх. То, что нажимаешь кнопочка вверх, там везде это пишется. **cd ..** — две точки — это директория выше текущей. Вот я нажимаю, оказываюсь в директории. Тильда — это тоже специальная директория, это сокращение, обозначающее домашнюю директорию. У каждого пользователя есть домашняя директория. Вот я сейчас нахожусь в домашней директории, в ней у меня есть директория **2023**, которую я заблаговременно создал для вас, для нас. Да, можно узнать полный адрес директории, в которой сейчас нахожусь, да, то есть команда **pwd** — **print working directory**. Вот в **Линуксе** вы будете, в **Линукс** подобных системах не так устроена дерево директории, как в **Винде**. В **Винде** там есть, значит, все начинается как бы с диска, у вас там с двоеточия, а потом слэш какие-то папки. В **Убунте**, в **Линуксе** есть так называемая корневая директория, которая обозначается просто слешом. Из нее растет вся файловая система. Файловая система вообще — это некоторые абстракция, которая позволяет вам воображать все, что хранится в вашем компьютере. Она вот как бы в виде дерева представлена. При этом, как оно соответствует физическим дискам — это отдельный вопрос, который мы не будем сейчас поднимать. В общем, как-то. И у меня есть директория, которая начинается с флешом — это корневая директория. Вот, и я могу из нее растет все мое дерево директории. Я могу сказать **cd home/ваше_имя_пользователя**. Вот, сразу же очень важный пункт. Да, если у кого из вас **Убунта** или у кого **macOS**, то вы можете сразу за мной повторять. Это, ну, в принципе, я думаю, если у кого **Убунта** или **macOS**, вы так это все умеете делать, скорее всего. А у кого **Винда** или что-то другое, то вы можете, не знаю, записывать, ну, или в каком-нибудь терминале в интернете пробовать это воспроизводить. Значит, я могу использовать клавишу **Tab**, чтобы дополнить, чтобы он мне подсказал, чем могу дальше написать. Вот, когда пишут **Tab**, он мне продолжает слово, которое начал писать, исходя из того, что есть там, ну, либо предлагает варианты дальше. Вот, например, я хочу дальше **2020**, и вот он мне предлагает, какие варианты есть. Тут **2023** прод, и вот я перешел сюда. Я могу также писать **cd ..** — две точки, две точки, две точки, и это как бы я на три директории вверх прошел. Вверх, потом еще вверх, относительно еще вверх, относительно вернулся в корень. Вот, я могу, кстати, да, спасибо, это очень полезное замечание, чуть не забыл. Очень полезная команда, которую не все далеко знают, но она супер полезна. Я не узнал тоже уже, когда был стажёром в **Яндексе** своему, потому что тогда никто на первом курсе таких вещей нам не рассказывал, и на втором, и на третьем. В общем, есть замечательная команда **cd -**. Очень полезная штука, возвращать туда, где были до этого. Но, к сожалению, работает только один раз. Если напишу **cd -** еще, то я, ну, буду ходить между ними просто. Вот, если вам хочется ходить, ну, как бы вот назад, назад, назад относительно, где вы были, то есть специальные команды **pushd** и **popd**. Я не буду про них сейчас подробно говорить, но если вам интересно, погуглите. Команды поддерживают стек директорий, в которых вы были, позволяют по нему ходить взад-вперед. Хорошо, еще одна полезная команда — посмотреть, что лежит в текущей директории, список файлов просто отобразить. Это команда **ls**. Вот команды, которые я сейчас озвучиваю, от команды **cd**. Она и в терминале **Винды** такая же. **cd** в **Винде** тоже есть. На **макосе** все то, что я сейчас говорю, работает также. Ну, короче, все то, что сейчас говорю, актуально для **Linux**, для **макос** и для **Винды**. **pwd**, по-моему, называем вместо **pwd** команда **dir**, которая отображает текущую директорию, а вместо **ls** команда **dir**. А вместо **pwd** не помню, какая команда. Ну, неважно. **ls** от слова **list**. Название команд в **Линуксе** порой странноватые. Ну, в общем, **ls** означает отобразить список файлов текущей директории. Вот список файлов текущей директории, они все почти синим цветом. Да, можно писать... Сейчас, подожди, подожди. Вот почти все файлы здесь синим цветом, это значит, они сами директории. Вот синим вот таким цветом отображается директория, вот таким голубеньким цветом отображаются ссылки. Ну, в терминах **Винды** это ярлыки. То есть это файл, который является ссылками на другие файлы на самом деле. А вот так я не помню, что отображается вот такой зеленой подсветкой. Ну, неважно. В общем, красным цветом отображаются архивы. Ну, короче, если мы не будем углубляться, вы можете почитать любой мануал по **Unix** для новичка, там будут все эти перечисленные штуки. Нам это не нужно, не будем углубляться в подробности, какие бывают файлы — это все будет у нас потом. Ну или потом на втором курсе у вас будет полезная команда. Можно добавить параметр, не знаю, сокращение какого слова **-l**, но **ls -l** означает отобразить подробно про каждый файл. Отображает даже позже, да. Или с **-l** — это значит отобразить подробно про каждый файл. Пишется, вот это какие у него есть права, какие права на доступ к этому файлу. Это, это даже не знаю, что это такое. Что это за поле? Нет, размер здесь. А это, ладно, давайте, к сожалению, не помню, не буду вас обманывать, что это. Это кто владелец этого файла. Это, по-моему, группы владельцев этого файла. Это размер, это дата последнего изменения. Вот про ярлыки, то есть по ссылке здесь написано, что, собственно, они ссылаются. Наверное, стоит поподробнее сказать по поводу прав. Вот эта строка, обозначающая права доступа к файлу, здесь есть несколько символов. Первый символ — это буква, обозначающая тип файла. Типы файлов в **Линуксе** бывают. Это бывают обычные файлы. Вот это, например, обычный файл. И такое, что она обычный. Если задуматься, но с точки зрения **Линукса** это обычный файл, поэтому здесь стоит прочерк. Вот директория — это особый тип файлов, для них написано **D**. Для файлов, которые являются ссылками, это тоже особый вид файлов, это **L** от слова **Link**. Вот бывают еще другие виды файлов, но мы не будем, опять-таки, углубляться. Пока достаточно этих. Дальше перечислены права доступа к файлам: **R**, **W** и **X**. **R** — от слова **read**, **W** — от слова **write**, **X** — от какого слова? От слова **execute**. Значит, буква **R** обозначает, что присутствует право на чтение этого файла. **W** — это значит, присутствует право на запись в этот файл. **X** означает, что присутствует право на выполнение этого файла. Почему-то это дублируется два раза. Вот почему у каждого файла есть три группы, ну, права доступа к файлу бывают трех категорий, скажем так. Первые три буквы обозначают права доступа к этому файлу у владельца этого файла. Владелец этого файла — **root**. То есть не важно, кто такой **root**. В общем, есть некоторые пользователи, которые зовут **root**. Пока что абстрактно. Ну вот, меня зовут вот так, да, **миссиярик**. И если бы я был владельцем, то вот эти три буквы обозначали бы права мои на действия с этим файлом. Я имею право читать этот файл, писать этот файл, выполнять этот файл. Вот эти вторые три буквы обозначают, то какие есть права к этому файлу у так называемых группы владельцев этого файла. В **Линуксе** у каждого файла есть не только пользователь-владелец, но еще и группа-владелец. Ну, просто когда пользователей в системе слишком много, они иногда объединяются в группы, и группы могут права отдельно настраиваться. Например, может быть группа администраторы или группа там разработчики или группа тестировщики, если мы говорим о каком-нибудь индексовом серваке. Вот, но в нашем случае это неприменимо, когда у вас будут большие сложные, там, большие сервера, там, где будет много пользователей, возможно, группа владельца вам будет о чем-то говорить. Последние три буквы — это права у всех остальных. Если вы, если вы владелец этого файла, то вам применяются вот эти вот права. Если вы в группе владельцев, применяются эти права. Если вы кто-то другой, только он применяется эти права. Количество харлинков на этот файл, я понял. Ну да, это количество, значит, файлов файловой системе, которые жестко ссылаются на этот же файл. Окей, хорошо. А, ну вот вопрос, например. Вопрос такой: почему? Ну что такое? Понятно, читать, писать — это понятно, что значит. Ну, читать — смотреть содержимое, писать — ты знаешь, менять содержимое. Что такое **X**? Почему **X** — это какое-то отдельное действие, на которое нужно отдельное право? Вот что за право? Особенно на выполнение. Почему, типа, почему если я читаю, то я выполнить не могу этот файл? В чем разница между чтением и выполнением? Кто может объяснить? Да, применительно к директориям **X** означает, что я имею право открыть директорию, а применительно к обычным файлам — что означает право на выполнение? Ну вот, например, давайте так скажу. Вот смотрите, вот у меня есть папочка **bin**. Давайте перейду в папочку **bin**. Я напишу **ls**. Тут очень много всего лежит. Ну, **bin** — это директория, в которой хранятся по сути все бинарники. То есть все, все программы, все исполняемые файлы данного компьютера, которые как бы в ней. Ну, в ней, не знаю, что лежит. Ну, например, в ней лежит такой файл, который называется **cd**, а **cd**, наверное, лежит **user**. Ну, хорошо, вот файл **cat**, например, лежит. **Cat** — это тоже команда, которая выводит на экран содержимое файла. Ну, короче, все команды на самом деле — это некоторые же программы, и они вот сами файлы этих программ лежат здесь. Не знаю, может быть, ты прав, но я не знаю. Не будем об этом, лучше. В общем, здесь лежат разные программы, всякие там у меня много всего установлено. Сейчас весь мир, весь мир увидит, какие у меня программы установлены. Вроде здесь ничего такого компрометирующего нет. В общем, это все некоторые программы. Да, вот, кстати, зеленым отображаются исполняемые файлы, запустить можно. А вот это ссылки, опять-таки, голубенькие — это ссылки. Так вот, ой, вот и вот если я напишу **ls -l** в этой директории, то тут у большинства файлов есть право на выполнение. Но, а владелец у них у всех **root**. Но почему же мне отдельным правом все-таки нужно выполнение? Почему чтение недостаточно? Ответ таков: дело в том, что выполнение по сути представляет из себя загрузку в оперативную память и восприятие того, что написано в этом файле, как инструкции процессора. Одно дело — вы можете просто посмотреть, что там написано, а другое дело — вы можете заставить процессор воспринять это как бинарный код и начать исполнять это, как будто это инструкция для процессора. Это совершенно разные вещи. Если у вас какой-нибудь вирус очень вредный или там какой-нибудь файл, в котором потенциально опасные какие-нибудь содержатся действия, ну, процессор бинарным кодом кодируется то, что он делает. И, допустим, у вас есть файл, который содержится очень опасный вирус, который там все крушит, ломает. Если у вас есть право на чтение этого файла, вы можете безопасно читать, но у вас не будет права, пока у вас нет права **X**. Это значит, что вы не сможете процессор заставить начать эти инструкции исполнять, как будто это бинарный код. Исполняемый. В этом разница между правом на чтение и правом на выполнение. Иметь право читать какой-то файл — это еще не значит иметь право выполнить его. Вот, и на самом деле все эти права нужны для того, чтобы безопасность была. То есть как раз право на выполнение лучше не давать тем файлам, которые потенциально возможно что-то плохое делают. Да, если у тебя есть право на запись в какой-то файл, ты можешь создать файл, который ты можешь читать, писать и выполнять. Ты берешь какой-то плохой файл и с помощью него копируешь содержимое в файл, который ты не мог выполнять, и выполняешь этот файл. Да, ты можешь так сделать. Но смысл же ограничений в том, чтобы ты случайно не сделала что-то плохое, а не в том, чтобы ты намеренно что-то плохое не сделал. Понятно, что таким способом ты можешь намеренно запустить что-то плохое. Команда `cat` — следующая полезная команда. Что вы думаете, она делает? Как следует из названия, это программа, которая происходит от слова "конкатенация". Но по факту это программа, чаще всего используемая, чтобы вывести содержимое файла на экран. Например, давайте выведем на экран какой-нибудь файл, который не очень большой. `cat Z` — всего лишь 1984 байта в этом файле. Давайте прочитаем их. Ой, ничего не вышло. Вот оно что! Для бинарных файлов эта команда выводит их содержимое на экран. А это не бинарный файл, это скрипт. Значит, `cat` — это был не бинарный файл, а просто скрипт с таким содержимым. Давайте сделаем `cat` на файл, который мы создали. Вот мы вывели на экран содержимое файла `cat`. Это был бинарный файл, и в нем была собственно исполняемая программа, записанная бинарным кодом. Как вы видите, здесь в общем-то ничего не понятно. Ладно, давайте вернемся в домашнюю директорию. Кстати, я написал `cd` без параметров. Заметьте, без параметров это значит вернуться домой. Да, вернулись на базу, так сказать. Честно говоря, я даже, наверное, больше не буду вам показывать другие команды на первое время. Мне хватит этих. Я потом, наверное, в какой-то момент вернусь к разговору про терминал, и мы с вами поделаем что-то более интересное. Пока что мне достаточно только вот этих базовых команд. Я умею водить, переходить в другие директории, смотреть через директории. Теперь я хочу из терминала написать какую-нибудь простейшую программу на плюсах, скомпилировать и запустить. Для этого я должен использовать какой-то текстовый редактор. Как знают давние почитатели моих видеолекций, мы будем использовать `vim`. Нет, вы будете использовать некоторые встроенные текстовые редакторы. Один из таких текстовых редакторов — это `nano`. Можете самостоятельно упражняться в его использовании. Но, пожалуй, самый такой трушный текстовый редактор для настоящих пацанов — это `vim`. А дальше название файла, который хотите создать. Если этот файл уже существовал, то он откроется, а если нет, то он будет создан. В этой директории у меня ничего нет, она сейчас пустая, и я сейчас открою файл `vim 1.cpp`. Я буду файлы нумеровать согласно пунктам нашей программы. Это файл, соответствующий первому параграфу первой главы. Теперь это значит расширение, чаще наш любимый язык программирования. Вот я открыл `vim`, теперь могу писать код. Да, кстати, я вижу, что увеличил и уменьшил шрифт. Чтобы увеличить, нажимаю `Ctrl` и `+`, чтобы уменьшить — `Ctrl` и `-`. А самое главное знание — как выйти из него. Есть такой анекдот, который рассказывают. Первый из них: мой приятель пользуется им уже 20 лет, потому что не знает, как из него выйти. Как выйти из `vim`? Нужно писать `:wq` и `Enter`. А теперь вы знаете, как выйти из `vim`. Но это был выход без сохранения изменений. Чтобы выйти с сохранением изменений, нужно написать `:wq` и `Enter`. Я сейчас снова зайду. Да, сейчас у меня никакого файла не создалось, потому что ничего не сохранил. Я сейчас снова открою тот же самый файл, на этот раз запишу и сохраню изменения. Я хочу повторить команду, которая была до этого. У меня есть стрелочка вверх, чтобы повторять команды. Я могу вверх-вниз делать, нажимая на клавиатуре стрелочку вверх, и отображается последняя команда, которую я вводил. Нажимаю еще раз вверх, и предпоследняя отображается. Так могу ходить вверх-вниз. В какой-то момент вы узнаете, какие команды вводил до того, как началась наша пара. Вы уже это увидели. Но я теперь иду вниз, дохожу до низа. Можно еще много интересного делать с историей команд, но про это потом расскажу вам. Пока это не нужно. Вот я повторяю эту команду, нажимаю. Теперь я хочу начать вводить текст. Чтобы начать вводить текст, мне нужно перейти в режим вставки. По умолчанию я нахожусь в режиме команд. Если сейчас буду какие-то буквы набирать на клавиатуре, то это будут не символы, которые печатаю, а будут какие-то странные вещи происходить, потому что он будет воспринимать мои нажатия как команды. Я хочу перейти в режим вставки. Чтобы перейти в режим вставки, мне нужно нажать клавишу `i`. Вот я ее нажал, и у меня внизу появилась `INSERT`. Это значит, я нахожусь в режиме вставки. Теперь я могу печатать, как будто я в обычном текстовом редакторе. Впрочем, тут есть несколько странных подводных камней. Некоторые вещи работают не так, как в обычном текстовом редакторе, но в целом, в основном, я могу писать, как в текстовом редакторе. Две полезных комбинаций клавиш, которые сразу же озвучу: если я хочу стереть целое слово, то я нажимаю `Ctrl + W`, а если я хочу стереть целую строку в режиме вставки, нажимаю `Ctrl + U`. Кстати, это же работает в терминале. Если у вас очень длинная команда и вы хотите стереть последнее слово, то вы нажимаете `Ctrl + W`, а если хотите стереть всю строку, то нажимаете `Ctrl + U`. Это полезно, особенно на `macOS`, на котором очень медленно стрелочка влево ездит. Если вы стираете на `macOS`, на котором по умолчанию медленный повтор клавиш, это меня бесит. Если вы хотите стереть целую длинную команду в терминале, используйте `Ctrl + U`. Так, ладно, третья попытка. Я попытаюсь написать какую-то программу на плюсах. Давайте будет такая программа: я объявлю целочисленную переменную `x`, введу с клавиатуры и выведу на экран ее же, увеличенную на 5. Очень интеллектуальная программа. Понятно, что `std::cout` — это такое заклинание, которое позволяет мне начать пользоваться стандартным выводом в моей программе. Понятно также, что моя программа начинается с функции `main`. Это точка входа в программу. Эта функция `main` обычно не будет принимать параметров, у нее возвращаемый тип `int`, потому что так надо. Возможно, в какой-то момент поподробнее остановимся на том, что именно может принимать функция `main`, что она может возвращать, что это все означает. Но пока что мы будем считать, что `main` у нас ничего не принимает и возвращает `int`. И `#include
Залогинтесь, что бы оставить свой комментарий