---
course: ОАиП
lecture: 1
title: "Лекция №1. Введение. Основные понятия. Инструменты разработчика. Структура программы."
---

# Лекция №1. Введение. Основные понятия. Инструменты разработчика. Структура программы.

## §1.1 Языки программирования. Классификация языков программирования

Представьте, что вы хотите дать компьютеру инструкции: «включи свет», «открой дверь», «посчитай сумму двух чисел». Но компьютер не понимает человеческий язык. Он работает на машинном языке — это язык из нулей и единиц, который процессор может выполнять напрямую. Однако писать программы в виде последовательности 0 и 1 крайне неудобно: это медленно, трудно читать, легко ошибиться и практически невозможно отлаживать.

Чтобы упростить общение с компьютером, были созданы **языки программирования** — формальные искусственные языки, предназначенные для записи **алгоритмов**, которые компьютер может выполнить.

То есть, **язык программирования** — это средство общения человека с компьютером, посредством которого мы описываем **алгоритмы** — последовательности шагов для решения задач.

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

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

**Лексика**

— совокупность слов того или иного языка, части языка или слов, которые знает тот или иной человек или группа людей.

**Синтаксис**

— сторона языка программирования, которая описывает структуру программ как наборов символов (обычно говорят — безотносительно к содержанию).

**Синтаксису** языка противопоставляется его семантика. Синтаксис языка описывает «чистый» язык, в то же время семантика приписывает определенные действия различным синтаксическим конструкциям.

**Семантика в программировании**

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

Без языков программирования невозможно создавать программы. А программы — это основа всего, что делает компьютер: от простого калькулятора до сложных систем искусственного интеллекта.

Основные цели **языков программирования**:

- **Упростить процесс написания программ** — вместо 0 и 1 можно писать понятные команды.
- **Сделать код читаемым и понятным** — не только для компьютера, но и для других программистов.
- **Обеспечить переносимость** — одна и та же программа может работать на разных компьютерах.
- **Повысить надёжность и безопасность** — языки помогают избегать ошибок и контролировать поведение программы.

Существует множество критериев, по которым можно классифицировать языки программирования. Частые варианты классификации представлены ниже:

- **По парадигме** (*декларативные, императивные, структурированные* и т.п.).
- **По системе типов** (*динамические, статические, сильно- и слаботипизированные, нетипизированные* и т.п.).
- **По уровню абстракции** (*высокого, низкого уровня*).
- **По модели исполнения** (*компилируемые, интерпретируемые*).

Четкой классификации не существует, по той простой причине, что существуют буквально тысячи ЯП, и в любой категории классификации обнаруживается практически непрерывный спектр.

На рисунке 1 представлена схема классификации ЯП на процедурные и непроцедурные.

![Рисунок 1 – Классификация Языков Программирования](/images/lectures/oaip/01/image-01.webp)

**Императивное программирование**

— это парадигма программирования (стиль написания исходного кода компьютерной программы), для которой характерно следующее:

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

**Императивная программа** похожа на приказы, выражаемые повелительным наклонением в естественных языках, то есть представляют собой последовательность команд, которые должен выполнить компьютер.

**Декларативное программирование**

— это парадигма программирования, в которой задаётся спецификация решения задачи, то есть описывается, что представляет собой проблема и ожидаемый результат.

**Процедурное программирование**

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

**Процедурные языки** разделяют на **языки низкого** и **высокого уровня**.

**Язык низкого уровня**

– это язык программирования, предназначенный для определенного типа компьютера и отражающий его внутренний машинный код.

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

**Язык высокого уровня**

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

**Объектно-ориентированное программирование (ООП)**

— методология программирования, основанная на представлении программы в виде совокупности объектов, каждый из которых является экземпляром определённого класса, а классы образуют иерархию наследования.

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

Примеры объектно-ориентированных языков: *Object Pascal, C++, C#, Java, JavaScript, Objective-C, PHP, Python*.

**Функциональное программирование**

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

Один из основных элементов в **функциональных языках – рекурсия**, т.е. вычисление значения функции через значение этой же функции от других элементов. Присваивания и циклов в классических функциональных языках нет. Представителями этой группы являются *ЛИСП*, *ML* и *Haskell*.

**Логическое программирование**

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

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

Классическим языком логического программирования считается *ПРОЛОГ*. Построение логической программы вообще не требует алгоритмического мышления, программа описывает статические отношения объектов, а динамика находится в механизме перебора и скрыта от программиста.

## §1.2 История развития языков программирования

История языков программирования началась в середине XX века, когда программисты писали код в двоичных 0 и 1. Это было сложно и неудобно. Уже в 1940-х появился **ассемблер** — первый шаг к упрощению, где команды стали записываться словами, близкими к машинным операциям.

В 1957 году появился **Fortran** — первый язык высокого уровня, созданный для научных расчётов. Он позволил записывать формулы почти как в математике. В 1959 году был разработан **COBOL** — язык для бизнеса и финансовых систем, с синтаксисом, напоминающим английский.

В 1960-х годах возник **ALGOL** — теоретическая основа многих современных языков. А в 1970-х на его основе появился **Pascal**, ставший популярным в обучении. Тогда же в Bell Labs был создан **C** — мощный и гибкий язык, на котором писали операционные системы, включая Unix.

В 1980-х, чтобы управлять ростом сложности программ, появилось объектно-ориентированное программирование. В 1983 году вышел **C++** — расширение C с поддержкой классов и объектов. В это же время был разработан **Ada** — строгий, надёжный язык, созданный по заказу Пентагона для авиации и военных систем. Он до сих пор используется там, где важна безопасность и точность.

В 1990-х с развитием интернета появились новые языки. В 1991 году — **Python**, простой и читаемый, позже ставший лидером в науке и AI. В 1995 году — **Java**, кроссплатформенный язык с виртуальной машиной. **JavaScript** — для интерактивности в браузерах и **PHP** — для динамических сайтов.

В 2000 году Microsoft представила **C#** — современный язык, похожий на Java, но для платформы .NET. Он стал основным для Windows-приложений и игр на Unity.

В 2000-х и 2010-х появились новые языки: **Go** (*Google*) — для серверов и высокой производительности. **Rust** — безопасная альтернатива языку программирования C++, предотвращающая ошибки в памяти.

Сегодня нет одного «главного» языка. Выбор зависит от задачи: **Python** — для анализа данных, **JavaScript** — для веба, **C#** — для приложений, **C** и **Rust** — для системного программирования. Языки продолжают развиваться, становясь удобнее, безопаснее и понятнее человеку.

## §1.3 Системы программирования

**Система программирования**

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

Программные продукты данного класса поддерживают все этапы процесса программирования, отладки и тестирования создаваемых программ.

**Система программирования** включает следующие программные компоненты:

- Редактор кода.
- Транслятор с соответствующего языка.
- Компоновщик (редактор связей).
- Отладчик.
- Библиотеки подпрограмм.

**Редактор текста**

– это программа для ввода и модификации текста. Данные программы ускоряют процесс разработки и повышают качество программного кода.

Известные редакторы текста – *Sublime Text, Atom, Notepad++* и другие.

**Транслятор**

– это программа, предназначенная для преобразования программ, написанных на языках программирования, в программы на машинном языке.

Программа, подготовленная на каком-либо языке программирования, называется **исходным модулем**. В качестве входной информации трансляторы применяют исходные модули и формируют в результате своей работы **объектные модули**, являющиеся входной информацией для редактора связей.

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

Трансляторы делятся на два класса: **компиляторы** и **интерпретаторы**.

**Компиляторы** переводят весь исходный модуль на машинный язык.

**Интерпретатор** последовательно переводит на машинный язык и выполнят операторы исходного модуля.

Преимущество интерпретатора перед компилятором состоит в том, что программа пользователя имеет одно представление - в виде текста. При компиляции одна и та же программа имеет несколько представлений - в виде текста и в виде выполняемого файла.
Программа обычно состоит из нескольких отдельных частей, которые часто разрабатываются разными людьми. Например, программа «Hello, World!» состоит из части, которую написали вы, и частей стандартной библиотеки языка С++. Эти отдельные части (иногда называемые **единицами трансляции**) должны быть скомпилированы, а файлы с результирующим объектным кодом должны быть скомпонованы в единое целое, образуя выполняемый файл. Программа, связывающая эти части в одно целое, называется **компоновщиком** или **редактором связей**.

**Компоновщик, или редактор связей**

– системная обрабатывающая программа, редактирующая и объединяющая объектные (ранее оттранслированные) модули в единые загрузочные, готовые к выполнению программные модули.

**Загрузочный модуль** может быть помещен ОС в основную память и выполнен.

**Библиотека в программировании (Library)**

– это сборник подпрограмм или объектов, используемых для разработки программ. Можно сказать, и так: это набор классов, компонентов или модулей для разных задач.

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

**Ошибки**, обнаруженные **компилятором**, называются **ошибками времени компиляции**, **ошибки**, обнаруженные **компоновщиком**, называются **ошибками времени компоновки**, а **ошибки**, не обнаруженные на этих этапах и проявляющиеся при выполнении программы, называются **ошибками времени выполнения** или **логическими ошибками**.

Как правило, ошибки времени компиляции легче понять и исправить, чем ошибки времени компоновки.

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

**Отладчик** позволяет управлять процессом исполнения программы, является инструментом для поиска и исправления ошибок в программе. Базовый набор функций отладчика включает:

- Пошаговое выполнение программы (режим трассировки) с отображением результатов.
- Остановка в заранее определенных точках.
- Возможность остановки в некотором месте программы при выполнении некоторого условия
- Изображение и изменение значений переменных.

**Загрузчик**

– системная обрабатывающая программа. Загрузчик помещает объектные и загрузочные модули в оперативную память, объединяет их в единую программу, корректирует перемещаемые адресные константы с учетом фактического адреса загрузки и передает управление в точку входа созданной программы.

Большинство программистов предпочитают использовать **интегрированную среду разработки** (*Integrated Development Environment – IDE*), объединяющую этапы программирования, компиляции и компоновки в пределах единого пользовательского 10 интерфейса, предоставляющего также средства отладки, облегчающие обнаружение ошибок и устранение проблем. Наиболее популярные IDE – *Visual Studio, CLion, IntelliJ IDEA, Rider, Goland, WebStorm*.

## §1.4 Основные определения, составляющие структуру программы

Для написания компьютерных программ необходимо иметь понятие основных определений компьютерной программы.

**Компьютерная программа**

— это последовательность инструкций, которые сообщают компьютеру, что ему нужно сделать.

**Стэйтмент (англ. «statement»)**

— это тип инструкции в компьютерных программах. Стэйтмент в программировании — это то же самое, что и «предложение» в русском языке. Все стэйтменты в C++ и C# заканчиваются точкой с запятой.

Самые распространенные стейтменты представлены в таблице 1.

Таблица 1 – Виды стейтментов

| Наименование | Объявление | Описание |
| --- | --- | --- |
| **Стейтмент объявления** | `int x;` | Он сообщает компилятору, что х является целочисленной переменной. Все переменные в программе должны быть объявлены, прежде чем использованы. |
| **Стейтмент присваивания** | `x = 50;` | Здесь мы присваиваем значение 50 переменной х. |
| **Стейтмент вывода** | `cout << x;` | Мы выводим значение переменной х на экран. |

Компилятор также способен обрабатывать выражения.

**Выражение (англ. «expression»)**

— это объект, который создается для проведения вычислений и нахождения соответствующего результата.

Например, в математике выражение **2 + 3** имеет значение **5**. Выражения в языках программирования могут содержать:

- Отдельные цифры и числа (например, *2, 45*).
- Буквенные переменные (например, *х, у*).
- Операторы, в т.ч. математические (например, *+, -*).
- Вызовы функций (например, *callFunction()*).

Для наглядности разберем простой корректный стэйтмент присваивания:

wireframe

```
х = 2 + 3;
```

Здесь мы вычисляем результат сложения чисел **2 + 3**, который затем присваиваем переменной **х**.

В языках программирования стэйтменты объединяются в блоки — **функции**.

**Функция — это последовательность стэйтментов.**

Каждая программа в **C++** должна содержать главную функцию *main()* (в **C#** - функцию *Main()*). Именно с **первого стэйтмента**, находящегося в функции *«main()»*, и начинается **выполнение всей программы**.

## §1.5 Структура программы на С++

Программы на C++ пишутся в обычных текстовых файлах. Их принято сохранять с расширением: **.cpp** — наиболее распространённое (например, **main.cpp, program.cpp**).

Рассмотрим стандартную программу «Hello, world!»:

cpp

```cpp
#include <iostream>
int main()
{
   std::cout << "Hello, World!" << std::endl;
   return 0;
}
```

Эту программу можно разделить на 2 части: **директивы препроцессора**, которые начинаются с символа **#**, и **основную часть программы**, которая начинается с определения сигнатуры главной функции **int main()**.

### §1.5.1 Директива препроцессора #include

Как и предполагает название, **препроцессор** – это инструмент, который запускается перед фактическим началом компиляции. **Директивы препроцессора** – это команды препроцессору, они всегда начинаются со знака «решетка» (#).

В строке 1 листинга из пункта **§1.5** директива **#include** указывает препроцессору взять содержимое файла (в данном случае – **iostream**) и включить его в строку, где расположена директива.

**iostream**

– это стандартный файл заголовка, который включается потому, что она содержит определение объекта потока вывода данных cout, используемого в листинге **§1.5** из для вывода на экран сообщения «Hello, World!».

Компилятор смог откомпилировать строку 4 только потому, что мы заставили препроцессор включить определение объекта потока cout в первой строке.

### §1.5.2 Тело программы – функция main()

После директив препроцессора следует тело программы, расположении в функции **main()**. Исполнение программы **С++** всегда начинается здесь, поэтому функцию **main()** часто называют точкой входа в программу. По стандартному соглашению, перед функцией **main()** указывается тип **int**. Тип **int** в данном случае – это тип данных возвращаемого значения функции **main()**.

Рассмотрим подробнее строку 4, выполняющую задачу программы, представленной в пункте **§1.5**.

**cout («console-out» - вывод на консоль, произносится как «си-аут»)**

– оператор, выводящий на экран строку *«Hello, World!»*.

**cout**

– это поток, определенный в стандартном пространстве имен (поэтому и указывается *std::cout*), а то, что мы делаем – это помещаем текст строки *«Hello, World!»* в данный поток, используя оператор вывода в поток <<.

**Потоком (stream)** называется последовательность символов, записываемая или читаемая из устройства ввода-вывода некоторым способом. Термин «поток» подразумевает, что символы поступают и передаются последовательно на протяжении определенного времени.

Оператор **std::endl** используется для завершения строки, а ввод его в поток эквивалентен переносу строку. Оператор вывода в поток используется при необходимости вывода в поток каждого нового элемента.

Функции в языке С++ должны возвратить значение, если противное не указано явным образом.

**main()**

– это функция, всегда и обязательно возвращающая целое число. Традиционно программисты возвращают значение 0 в случае успешного выполнения программы и -1 в случае ошибки.

Язык С++ чувствителен к регистру. Поэтому готовьтесь к неудаче компиляции, если напишете **Int** вместо **int**, **Void** вместо **void** и **Std::Cout** вместо **std::cout**.

### §1.5.3 Концепция пространства имен

**Пространства имен**

– это множество, в рамках которого определяются различные идентификаторы (имена типов, функций, переменных и т. д.).

**Пространства имен** используются для организации кода в виде логических групп и с целью избежания конфликтов имен, которые могут возникнуть, особенно в таких случаях, когда база кода включает несколько библиотек. Все идентификаторы в пределах пространства имен доступны друг другу без уточнения.

Чтобы избежать конфликта имен, разрешается также объявлять собственные пространства имен через ключевое слово **namespace**. Всё, что объявлено внутри пользовательского пространства имен, — принадлежит только этому пространству имен. Для того, чтобы указать компилятору место поиска идентификатора в определенном пространстве имен необходимо использовать название необходимого пространства имен вместе с оператором разрешения области видимости (**::**) и требуемым идентификатором.

Причина использования в программе синтаксиса оператора **std::cout**, а не просто **cout**, в том, что используемый элемент (**cout**) находится в стандартном пространстве имен (**std**).

При вызове оператора **std::cout** вы указываете компилятору использовать именно тот объект, который доступен в стандартном пространстве имен **std**.

Объявление **using namespace std;**, представленное в листинге ниже, позволит избежать множественного написания **std**.

cpp

```cpp
#include <iostream>
int main()
{
   //Указать компилятору пространство имен для поиска
   using namespace std;
   cout << "Hello, World!" << endl;
   return 0;
}
```

### §1.5.4 Простые операторы ввода std::cin и вывода std::cout

Для записи простых тестовых данных на консоль используется оператор **std::cout** (произносится как *standard see-out – «стандарт си-аут»*) и оператор **std::cin** (произносится как *standard see-in – «стандарт си-ин»*) для чтения текста и чисел с консоли (как правило, с клавиатуры). Фактически при отображении слов *«Hello World»* на экране в листинге из пункта **§1.5** вы уже встречались с оператором **cout**:

cpp

```cpp
std::cout << "Hello World" << std::endl;
```

Здесь оператор **cout** сопровождается оператором вывода **<<** (позволяющим вставить данные в поток вывода), который подлежит выводу строковым литералом *«Hello World»* и символом новой строки в форме оператора **std::endl** (произносится как *standard endline (стандарт енд-лайн)*).

Применение оператора **cin** сопровождается указанием переменной, в которую следует поместить вводимые данные:

cpp

```cpp
std::cin >> ПЕРЕМЕННАЯ;
```

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

cpp

```cpp
std::cin >> ПЕРЕМЕННАЯ1 >> ПЕРЕМЕННАЯ2;
```

Обратите внимание на то, что оператор **cin** применяется для ввода как текстовых, так и числовых данных, как представлено в листинге ниже.

Операторы **std::cout** и **std::cin** являются частью стандартной библиотеки **C++** и работают с потоками ввода – вывода. Они определены в заголовочном файле **<iostream>**, который необходимо подключать в начале программы с помощью директивы **#include <iostream>**. Без этого подключения компилятор не будет распознавать **std::cout** и **std::cin**, что приведёт к ошибкам на этапе компиляции.

Также стоит отметить, что **std::cin** по умолчанию пропускает пробельные символы (пробелы, табуляции, переводы строк) при чтении данных.

Это означает, что если вы вводите строку с пробелами, например, *«Иван Иванов»*, то **std::cin >> name** прочитает только *«Иван»*. Чтобы считать всю строку целиком, включая пробелы, следует использовать:

cpp

```cpp
std::string full_name;
std::getline(std::cin, full_name);
```

Пример использоваия программы:

cpp

```cpp
#include <iostream>
#include <string>
using namespace std;
int main()
{
   // Объявление переменной для хранения целого числа
   int InNumber;
   cout << "Введите число: ";
   // Сохранить введенное пользователем целое число
   cin >> InNumber;
   // Аналогично с текстовыми данными
   cout << "Введите Ваше имя: ";
   string InName;
   cin >> InName;
   cout << InName << " ввел " << InNumber << endl;
   return 0;
}
```

Данная программа выведет следующий текст:

wireframe

```
Результат выполнения программы:

Введите число: 2025

Введите Ваше имя: Александр

Александр ввел 2025
```

## §1.6 Структура программы на C#

Программа на **C#** строится на основе классов и методов. В отличие от **C++**, где программа начинается с функции **main**, в **C#** точкой входа является статический метод **Main** внутри класса.

Минимальная программа на C# выглядит так:

csharp

```csharp
class Program
{
    static void Main()
    {
        // Код программы
    }
}
```

### §1.6.1 Инструкции и блоки кода в C#

Базовым строительным блоком программы являются инструкции (*statement*). Инструкция представляет некоторое действие, например, арифметическую операцию, вызов метода, объявление переменной и присвоение ей значения. В конце каждой инструкции в C# ставится точка с запятой (;). Данный знак указывает компилятору на конец инструкции. Например:

csharp

```csharp
Console.WriteLine("Привет");
```

Данная строка представляет вызов метода **Console.WriteLine()**, который выводит на консоль строку. В данном случае вызов метода является инструкцией и поэтому завершается точкой с запятой.

Набор инструкций может объединяться в блок кода. Блок кода заключается в фигурные скобки, а инструкции помещаются между открывающей и закрывающей фигурными скобками:

csharp

```csharp
{
    Console.WriteLine("Привет");
    Console.WriteLine("Добро пожаловать в C#");
}
```

### §1.6.2 Тело программы – класс Program и метод Main()

В языке C# программа устроена иначе, чем, например, в C или C++. Здесь всё — **объект**. Даже самая простая программа должна быть обёрнута в класс, потому что C# — это чистый **объектно-ориентированный язык**.

Обычно основной класс называется **Program** (хотя можно дать и другое имя). В этом классе обязательно должен быть специальный метод — *Main()*. Именно он является точкой входа в программу.

**Метод «Main()»**

— это как «стартовая кнопка» программы. Без него программа не запустится, потому что компьютер не будет знать, с какой строки начинать выполнение. Внутри этого метода вы можете писать команды, которые будут выполняться: выводить текст, выполнять расчёты, запрашивать данные у пользователя и так далее.

Когда вы запускаете приложение, среда выполнения **.NET** ищет метод **Main** и начинает выполнение с него.

csharp

```csharp
using System; // подключаемое пространство имен
namespace HelloApp // объявление нового пространства имен
{
   class Program // объявление нового класса
   {
      static void Main()
      {
         Console.WriteLine("Hello World!");
      }
   } // конец объявления нового класса
} // конец объявления нового пространства имен 
```

Разберём детали:

- **class Program** — объявление класса с именем Program. Это обычный класс, как и любой другой, но именно в нём принято размещать точку входа. В новых версиях языка разрешается упускать написание класса Program.
- **static** — ключевое слово, означающее, что метод принадлежит самому классу, а не экземпляру (объекту). Так как программа ещё не создала объектов, Main должен быть static, чтобы его можно было вызвать без создания экземпляра класса.
- **void** — указывает, что метод ничего не возвращает. В C# Main может также возвращать int (для кодов завершения), но void — проще и чаще используется в учебных примерах.
- **Main()** — имя метода. Пишется с большой буквы, и оно строго фиксировано: только Main, иначе среда не найдёт точку входа, что приведет к поломке Вашей программы.
- **Фигурные скобки { }** — определяют тело метода. Всё, что между ними, будет выполнено при запуске программы.

### §1.6.3 Консольный ввод и вывод данных. Команда Console

В листинге из пункта **§1.6.2** в строчке 8 мы видим метод консольного вывода, который выполняет лишь одно действие, выводит строчку *«Hello World»*.

Есть другой способ вывода на консоль сразу нескольких значений, который показан в листинге ниже.

csharp

```csharp
using System;
namespace HelloApp
{
   class Program
   {
      static void Main(string[] args)
      {
         string name = "Tom";
         int age = 34;
         double height = 1.7;

         Console.WriteLine("Имя: {0} Возраст: {2} Рост: {1} м", name, height, age);
         Console.ReadKey();
      }
   }
} 
```

Этот способ подразумевает, что первый параметр в методе **Console.WriteLine** представляет выводимую строку ("Имя: {0} Возраст: {2} Рост: {1}м"). Все последующие параметры представляют значения, которые могут быть встроены в эту строку (name, height, age). При этом важен порядок подобных параметров.

Кроме вывода информации на консоль мы можем получать информацию с консоли. Для этого предназначен метод **Console.ReadLine()**. Он позволяет получить введенную строку.

Для наглядности работы команды **Console.ReadLine** посмотрите на код ниже:

csharp

```csharp
using System;
namespace HelloApp
{
   class Program
   {
      static void Main(string[] args)
      {
         Console.Write("Введите свое имя: ");

         // вводим имя
         string name = Console.ReadLine();

         // выводим имя на консоль
         Console.WriteLine($"Привет {name}");
         Console.ReadKey();
      }
   }
}
```

Чтобы ввести значение переменной name внутрь выводимой на консоль строки, применяются фигурные скобки {}. То есть при выводе строки на консоль выражение {name} будет заменяться на значение переменной name – введенное имя.

Однако, чтобы можно было вводить таким образом значения переменных внутрь строки, перед строкой указывается знак доллара $. Данная операция называется **интерполяция**.

Однако минусом этого метода является то, что **Console.ReadLine** считывает информацию именно в виде строки. Поэтому мы можем по умолчанию присвоить ее только переменной типа **string**.

По умолчанию платформа **.NET** предоставляет ряд методов, которые позволяют преобразовать различные значения к типам **int**, **double** и т.д.

Некоторые из этих методов:

- **Convert.ToInt32() / int.Parse()** – преобразует к типу **int**.
- **Convert.ToDouble() / double.Parse** – преобразует к типу **double**.
- **Convert.ToDecimal() / Decimal.Parse** – преобразует к типу **decimal**.

csharp

```csharp
string name = Console.ReadLine();
int age = Convert.ToInt32(Console.ReadLine());
double height = Convert.ToDouble(Console.ReadLine());
decimal salary = Convert.ToDecimal(Console.ReadLine());
```

C# является регистрозависимым языком. Это значит, в зависимости от регистра символов какое-то определенные названия может представлять разные классы, методы, переменные.

Например, название обязательного метода **Main** начинается именно с большой буквы: *«Main»*. Если мы назовем метод *«main»*, то программа не скомпилируется, так как метод, который представляет стартовую точку в приложении, обязательно должен называться *«Main»*, а не *«main»* или *«MAIN»*.

## §1.7 Использование комментариев в коде

**Комментарий**

– это способ размещения произвольного текста внутри кода программы. Комментарии игнорируются компилятором и обычно используются программистами для объяснений в коде.

Различают два вида комментариев:

**1. Символ // означает, что следующая строка – комментарий.**

Например:

text

```text
// Это комментарий
```

**2. Текст, содержащийся между символами `/* и */`, также являются комментариями, даже если он занимает несколько строк.**

Например:

text

```text
/* Это комментарий, 
Занимающий 2 строки /*
```

## §1.8 Пример обработки синтаксических ошибок

При написании программ, особенно в начале обучения, ошибки — это нормально. Более того, они неизбежны. Одни из самых частых — синтаксические ошибки, то есть нарушения правил языка программирования: пропущенные точки с запятой, несогласованные скобки, опечатки в ключевых словах и т.д.

Компилятор (в C++) или среда разработки (в C#) не пропустит такие ошибки. Вместо запуска программы вы получите сообщение об ошибке. Умение понимать эти сообщения — важный навык начинающего программиста.

Рассмотрим типичные синтаксические ошибки на примерах в C++ и C#.

Пример программы с намеренными ошибками:

cpp

```cpp
#include <iostream>
 
int main()
{
    cout << "Привет, мир!" << endl
    return 0;
```

В данном коде следующие ошибки:

- Нет std:: перед cout и endl (если не используется using namespace std;).
- Пропущена точка с запятой после endl.
- Фигурная скобка открыта, но не закрыта.

После того, как компилятор поймет, какие ошибки есть в программе, он выведет следующие сообщения об ошибке:

- «error: 'cout' was not declared in this scope» — означает, что cout не найден. Нужно писать std::cout или добавить using namespace std;.
- «error: expected ';' before 'return'» — говорит, что перед return должна быть точка с запятой. Это потому, что оператор cout << ... не завершён.
  ― «error: expected '}' at end of input» — компилятор ждёт закрывающую скобку.

В С# ситуация аналогичная. Код с ошибками представлен ниже:

csharp

```csharp
using System
 
class Program
{
    static void Main()
    {
        Console.WriteLine("Привет, мир!")
    
}
```

В данном коде следующие ошибки:

- Пропущена точка с запятой после using System.
- Пропущена точка с запятой после WriteLine(...).
- Отсутствует закрывающая } у метода Main.

После того, как компилятор поймет, какие ошибки есть в программе, он выведет следующие сообщения об ошибке:

- «; expected» — ожидается точка с запятой. Появляется у using System.
- «Invalid token ')' in class, struct, or interface member declaration» — странная ошибка, но она возникает из-за пропущенной ; после WriteLine(...).
- «} expected» — компилятор сообщает, что не хватает закрывающей фигурной скобки.
