какую функцию должны содержать все программы на с
Урок №8. Структура программ
Компьютерная программа — это последовательность инструкций, которые сообщают компьютеру, что ему нужно сделать.
Стейтменты
Cтейтмент (англ. «statement») — это наиболее распространенный тип инструкций в программах. Это и есть та самая инструкция, наименьшая независимая единица в языке С++. Стейтмент в программировании — это то же самое, что и «предложение» в русском языке. Мы пишем предложения, чтобы выразить какую-то идею. В языке C++ мы пишем стейтменты, чтобы выполнить какое-то задание. Все стейтменты в языке C++ заканчиваются точкой с запятой.
Есть много разных видов стейтментов в языке C++. Рассмотрим самые распространенные из них:
int х — это стейтмент объявления (англ. «statement declaration»). Он сообщает компилятору, что х является переменной. В программировании каждая переменная занимает определенное число адресуемых ячеек в памяти в зависимости от её типа. Минимальная адресуемая ячейка — байт. Переменная типа int может занимать до 4 байт, т.е. до 4 адресуемых ячеек памяти. Все переменные в программе должны быть объявлены, прежде чем использованы. Мы детально поговорим о переменных на следующих уроках.
std::cout — это стейтмент вывода (англ. «output statement»). Мы выводим значение переменной х на экран.
Выражения
Функции
В языке C++ стейтменты объединяются в блоки — функции. Функция — это последовательность стейтментов. Каждая программа, написанная на языке C++, должна содержать главную функцию main(). Именно с первого стейтмента, находящегося в функции main(), и начинается выполнение всей программы. Функции, как правило, выполняют конкретное задание. Например, функция max() может содержать стейтменты, которые определяют большее из заданных чисел, а функция calculateGrade() может вычислять среднюю оценку студента по какой-либо дисциплине.
Библиотеки
Библиотека — это набор скомпилированного кода (например, функций), который был «упакован» для повторного использования в других программах. С помощью библиотек можно расширить возможности программ. Например, если вы пишете игру, то вам придется подключать библиотеки звука или графики (если вы самостоятельно не хотите их создавать).
Язык C++ не такой уж и большой, как вы могли бы подумать. Тем не менее, он идет в комплекте со Стандартной библиотекой С++, которая предоставляет дополнительный функционал. Одной из наиболее часто используемых частей Стандартной библиотеки C++ является библиотека iostream, которая позволяет выводить данные на экран и обрабатывать пользовательский ввод.
Пример простой программы
Теперь, когда у вас есть общее представление о том, что такое стейтменты, функции и библиотеки, давайте рассмотрим еще раз программу «Hello, world!»:
Строка №1: Специальный тип инструкции, который называется директивой препроцессора. Директивы препроцессора сообщают компилятору, что ему нужно выполнить определенное задание. В этом случае мы говорим компилятору, что хотели бы подключить содержимое заголовочного файла к нашей программе. Подключение заголовочного файла дает нам возможность использовать функционал библиотеки iostream, что, в свою очередь, позволяет выводить нам данные на экран.
Строка №2: Пустое пространство, которое игнорируется компилятором.
Строка №3: Объявление главной функции main().
Строки №4 и №7: Указываем компилятору область функции main(). Всё, что находится между открывающей фигурной скобкой в строке №4 и закрывающей фигурной скобкой в строке №7 — считается содержимым функции main().
Строка №6: Оператор возврата return. Когда программа завершает свое выполнение, функция main() передает обратно в операционную систему значение, которое указывает на результат выполнения программы: успешно ли прошло выполнение программы или нет.
Синтаксис и синтаксические ошибки
Как вы, должно быть, знаете, в русском языке все предложения подчиняются правилам грамматики. Например, каждое предложение должно заканчиваться точкой. Правила, которые регулируют построение предложений, называются синтаксисом. Если вы не поставили точку и записали два предложения подряд, то это является нарушением синтаксиса русского языка.
Язык C++ также имеет свой синтаксис: правила написания кода/программ. При компиляции вашей программы, компилятор отвечает за то, чтобы ваша программа соответствовала правилам синтаксиса языка C++. Если вы нарушили правила, то компилятор будет ругаться и выдаст вам ошибку.
Например, давайте посмотрим, что произойдет, если мы не укажем в конце стейтмента точку с запятой:
Какую функцию должны содержать все программы на с
В данной главе определяются термины, которые позднее используются в данном Руководстве при описании языка С, и рассматривается структура исходного текста программы на языке С. Дается обзор некоторых характеристик языка С, которые находят свое подробное описание в других главах. В главах «Объявления» и «Функции» рассматривается синтаксис и значение объявлений и определений. Предпроцессор С и прагмы рассмотрены в разделе «Директивы предпроцессора и прагмы».
Исходная программа С это набор любого числа директив, прагм, объявлений, определений и операторов. Все эти конструкции кратко рассматриваются в последующих разделах. Чтобы эти конструкции имели смысл, они все должны иметь синтаксис, соответствующий приведенному в данном руководстве, хотя и могут следовать в программе в любом порядке (в соответствии со сформулированными в данном Руководстве правилами). Однако, порядок их появления влияет на использование переменных и функций в программе. (Дополнительная информация по данному вопросу содержится в разделе «Время и сфера действия».)
«Директива» содержит инструкции для предпроцессора С по выполнению некоторых действий над текстом программы до его компиляции.
«Прагма» дает задание компилятору выполнить конкретные действия во время компиляции.
Объявления и определения
«Объявление» устанавливает связь между именем и атрибутами переменной, функции и типом. В С все переменные должны быть объявлены до своего использования. «Определение» переменной устанавливает те же связи, что и объявление, но кроме этого переменной выделяется память. Т.о. все определения являются объявлениями, но не все объявления являются определениями. Например, объявление переменной, которое начинается со спецификатора класса хранения extern является скорее «ссылочным» объявлением, чем «определяющим». Ссылочные объявления не вызывают выделение памяти и не могут быть инициализированы. (Дополнительная информация по классам хранения содержится в главе «Объявления».)
«Объявления функций» (или «прототипы») устанавливают имя функции, ее возвращаемый тип и, возможно, ее формальные параметры. В определении функции присутствуют те же элементы, что и в ее прототипе, плюс тело функции. Если не сделать четкого объявления функции, то компилятор сам построит ее прототип на основании всей имеющейся информации при первой ссылке на функцию, является ли это ее определением или вызовом.
Объявления функций и переменных могут появляться как внутри так и вне определения функции. Любое объявление внутри определения функции считается «внутренним» (локальным). Объявление вне всех определений функций считается «внешним» (глобальным).
Определения переменных, как и их объявления, могут происходить как на внутреннем, так и на внешнем уровне. Определения функций всегда происходят на внешнем уровне.
Обратите внимание на то, что объявления типов (например, структур, об’единений и объявления typedef), которые не включают имена переменных объявленного типа, не вызывают выделения памяти.
В следующем примере показан исходный текст простой программы на С. В исходной программе определяется функция main и объявляется функция printf с прототипом. Программа использует определяющие объявления для инициализации глобальных переменных x и y. Локальные переменные z и w объявляются, но не инициализируются. Память выделяется для всех этих переменных, но только x, y, u и v имеют содержательные значения, т.к. они были инициализированы явно или неявно. Значения z и w не имеют смысла до тех пор, пока им не присваиваются значения в выполняемых операторах.
Исходную программу можно разделить на один или несколько «исходных файлов». (Например, исходный файл может содержать лишь несколько нужных программе функций.) При компилировании программы для получения общего текста нужно отдельно скомпилировать, а затем скомпоновать ее исходные файлы. Кроме того, можно использовать директиву #include для комбинирования нескольких исходных файлов в большой исходный файл до компиляции. (Информация по «включению» файлов содержится в главе «Директивы предпроцессора и прагмы».)
Исходный файл может содержать любую комбинацию полного набора директив, прагм, объявлений и определений. Нельзя разделять элементы (например, определения функций и большие структуры данных) между разными исходными файлами. Последним символом исходного файла должен быть символ новой строки.
Директивы исходного файла применяются только к этому файлу и включенным в него файлам. Более того, директива применяется только к той части файла, которая за ней следует.
Прагмы обычно воздействуют на указанную часть исходного файла. Реализация определяет заданные в прагме действия компилятора. (Руководство по компилятору подробно описывает эффект применения конкретных прагм.)
В следующем примере показана исходная программа С, состоящая из двух исходных файлов. После компиляции этих исходных файлов их можно скомпоновать и использовать, как одну программу.
Предполагается, что функции main и max находятся в разных файлах, и выполнение программы начинается с main.
Строки, которые начинаются с символа номера (#) являются директивами предпроцессора. Эти директивы информируют предпроцессор о том, что во всем исходном файле 1 нужно заменить идентификаторы ONE, TWO и THREE на указанные цифры. Однако, эти директивы никак не относятся к исходному файлу 2 (см. ниже), который будет скомпилирован отдельно и затем скомпонован с исходным файлом 1.
Каждая программа на С должна иметь главную функцию, которая должна иметь имя main. Функция main является стартовой точкой выполнения программы. Она обычно управляет выполнением программы, вызывая в нужный момент другие функции. Программа обычно заканчивает свое выполнение в конце функции main, хотя ее выполнение может быть прервано и в других точках программы в зависимости от условий ее выполнения.
Исходная программа обычно состоит из нескольких функций, каждая из которых выполняет одну или несколько конкретных задач. Функция main может вызывать эти функции для выполнения соответствующих им задач. Когда main вызывает другую функцию, она передает выполнение этой функции и ее выполнение начинается с выполнения первого оператора функции. Функция возвращает управление после выполнение оператора return или после достижения конца функции.
Можно объявить любую функцию, включая main, с параметрами. Когда одна функция вызывает другую, вызванная функция принимает значения своих параметров от вызвавшей ее функции. Эти значения называются «аргументами». Можно объявить формальные параметры в main так, что они могут принимать значения из внешней среды программы. (Чаще всего эти аргументы передаются из командной строки при выполнении программы.)
Традиционно первые три параметры функции main объявляются с именами argc, argv и envp. Параметр argc объявляется для хранения общего числа передаваемых в main аргументов. Параметр argv объявляется как массив указателей, каждый элемент которого указывает на строковое представление переданного в main аргумента. Параметр envp это указатель на таблицу строковых значений, которая устанавливает среду выполнения программы.
Операционная система присваивает значения параметрам argc, argv и envp, а пользователь вводит действительные аргументы в main. Операционная система, а не язык С, определяет преобразование при передаче аргументов в конкретной системе. Дополнительная информация по данному вопросу содержится в руководстве по компилятору.
При объявлении формальных параметров функции они должны быть объявлены при определении функции. Объявление и определение функций подробно рассмотрено в главах «Объявления» и «Функции».
Для того, чтобы понять, как работает программа на С, нужно сначала понять правила, которые определяют использование переменных и функций в программе. Для осознания этих правил важно понять три основные концепции: «блок», «время действия» и «сфера действия».
Блоки
Блок это последовательность объявлений, определений и операторов, которая заключена в скобки. В языке С есть два типа блоков. «Составной оператор» (более подробно рассмотренный в главе «Операторы») это один тип блока. Другой тип блока это «определение функции», которое состоит из тела функции и связанного с ней «заголовка» (имя функции, возвращаемый тип и формальные параметры). Блок может содержать в себе другие блоки за тем исключением, что блок не может содержать определения функции. О блоках внутри других блоков говорят, что они «вложены» в них.
Заметим, что хотя все составные операторы заключаются в скобки, не все заключенное в скобки есть составной оператор. Например, хотя спецификации массивов, структур и перечислимых элементов могут быть заключены в скобки, они не рассматриваются в качестве составного оператора.
Время действия
«Время действия» это период выполнения программы, в котором существует переменная или функция. Все функции программы существуют на всем протяжении выполнения программы.
Время действия переменной может быть внутренним (локальным) или внешним (глобальным). Элемент с локальным временем действия («локальный элемент») хранит и определяет значение только в блоке, в котором он был определен или объявлен. Локальному элементу всегда выделяется новое место в памяти каждый раз, когда программа входит в блок, и хранимая величина теряется, когда программа выходит из блока. Если время действия переменной глобально (глобальный элемент), то он хранит и определяет значение на всем протяжении выполнения программы.
Следующие правила определяют, имеет переменная глобальное или локальное время действия:
— Переменные, которые объявлены на внутреннем уровне (в блоке) обычно имеют локальное время действия. Можно задать для переменной в блоке глобальное время действия, если указать в ее объявлении спецификатор класса хранения static. После объявления static переменная будет хранить в себе значение от одного вызова блока до другого. Однако, к ней можно будет обратиться только в данном блоке или из вложенных в него блоков. (Доступ к элементам рассматривается в следующем разделе. Информацию о спецификаторах класса хранения можно найти в главе «Объявления».)
— Переменные, которые объявлены на внешнем уровне (вне всех блоков программы) всегда имеют глобальное время действия.
Сфера действия
«Сфера действия» элемента определяет ту часть программы, в которой на него можно сослаться по имени. Элемент доступен только в своей сфере действия, которая может быть ограничена (в порядке усиления ограничений) файлом, функцией, блоком или прототипом функции, в котором она появляется.
В С только имя метки всегда имеет сферой своего действия функцию. (Дополнительная информация по меткам и их именам содержится в главе «Операторы».) Сфера действия любого другого элемента определяется уровнем, на котором производится его объявление. Объявленный на внешнем уровне элемент имеет сферой своего действия весь файл и доступен из любого места файла. Если его объявление происходит в блоке (включая список формальных параметров в определении функции), то сфера действия элемента ограничивается данным блоком и вложенными в него блоками. Имена формальных параметров в списке параметров прототипа функции имеют сферу действия только от объявления параметра до конца объявления функции.
Хотя элемент с глобальным временем действия и «существует» на всем протяжении выполнения исходной программы (например, внешне объявленная переменная или локальная переменная, объявленная с ключевым словом static), он может и не быть доступен из всех частей программы.
Про элемент говорят, что он «глобально доступен», если он доступен или можно сделать соответствующее объявление для доступа к нему, из всех исходных файлов, составляющих программу. (Дополнительная информация по организации доступа между исходными файлами, известной как «компоновка», содержится в главе «Объявления».)
Краткий обзор
В Таблице 3.1 суммируются основные факторы, определяющие время и сферу действия переменных и функций. Однако, эта таблица не учитывает всех возможных вариантов. Дополнительная информация содержится в Главе «Объявления».
Следующий пример программы иллюстрирует блоки, вложение и доступ к переменным. В примере есть четыре уровня доступа: внешний и три уровня блоков. Предположим, что функция printf определена в каком-либо другом месте программы. Значения будут выводиться на экран так, как это показано в предшествующем каждому оператору комментарии.
В программе на языке С идентификаторы используются для ссылки на многие виды различных объектов. При написании программы на С идентификаторы используются для функций, переменных, формальных параметров, компонентов об’единений и других используемых в программе объектов. С позволяет использовать один идентификатор для нескольких элементов программы, если придерживаться правил, изложенных в этом разделе. (Определение идентификатора содержится в Главе «Элементы С».)
Компилятор устанавливает «классы» для того, чтобы различать идентификаторы, использованные для различных видов элементов. Чтобы не возникало конфликта, имя каждого класса должно быть уникальным, но в нескольких классах может быть использовано идентичное имя. Это значит, что можно использовать идентификатор для нескольких разных объектов, если эти объекты располагаются в разных классах. Компилятор может идентифицировать ссылку исходя из контекста использования идентификатора в программе. Следующий список описывает виды элементов, которым можно присваивать имена в программе на С и привила по присваиванию имен:
Три элемента с именем student в следующем примере не конфликтуют, т.к. признаки структур, компоненты структур и имена переменных находятся в трех разных классах. Контекст использования каждого элемента позволяет корректно интерпретировать каждое появление student в программе.
Структура программ на языке Си
Пожалуйста, приостановите работу AdBlock на этом сайте.
Я надеюсь вы уже установили себе на компьютер какую-нибудь IDE и научились в ней компилировать программы. Если нет, то подробная инструкция как установить IDE для языка Си.
Все программы, написанные на языке Си, имеют общую структуру. О которой мы и поговорим в этом уроке. В этом нам поможет наша первая программа, написанная на предыдущем шаге.
Будем заполнять простую карту. На данный момент мы знаем, что существуют программы, но как они устроены внутри нам неизвестно. Поэтому наша карта будет иметь следующий вид.
Рис.1 Карта «Структура программ на языке Си.» Начальный уровень.
На протяжении всего курса мы к этой карте будем возвращаться, уточнять её, дополнять новыми элементами и блоками.
Сейчас внимание. Не пугайтесь! Ниже написан исходный код трёх простеньких программ. Ваша задача внимательно на них посмотреть и попытаться найти в их коде какую-то закономерность (нечто общее, что есть в каждой программе).
Листинг 1. Программа 1. Печатает «Hello, World!»
Листинг 2. Программа 2
Листинг 3. Программа 3
Не торопитесь смотреть продолжение урока и правильный ответ на эту задачу. Для начала попробуйте ответить самостоятельно. После этого нажмите кнопку «Смотреть продолжение!»
Итак, ответ: Во всех программах выше присутствует следующая конструкция:
Остановимся на секундочку. Мы, кажется, уже кое-что выяснили о структуре программ на языке Си. Любая программа на языке Си должна содержать функцию main. Отобразим этот факт на нашей карте знаний «Структура программ на языке Си.»
Рис.2 Карта «Структура программ на языке Си.» Функция main.
Теперь карта не напрягает нас своей зияющей пустотой. Продолжим наши исследования.
Давайте я расскажу немного о функции main и о функциях вообще.
Перед именем функции написано int, это сокращение от слова integer, которое переводится с английского, как «целое». Подобная запись означает, что когда функция main завершит свою работу, она должна вернуть вызывающей программе (в нашем случае это операционная система) какое-нибудь целое число. Обычно, для функции main это число ноль, которое оповещает операционную систему: «Мол, всё хорошо. Происшествий не случилось.»
После имени функции в скобках записано слово void. Вообще в скобках обычно записывают аргументы функции, но в нашем случае, когда в скобках пишут void, это означает, что аргументов у функции нет. Другими словами, чтобы функция main начала работу ей не нужны никакие дополнительные данные извне. Мы ещё поговорим обо всём этом подробно, а пока просто запомним, что слово void вместо аргументов функции обозначает, что для данной функции никаких аргументов не требуется.
Внутри фигурных скобок идёт описание функции main, т.е. непосредственно то, что эта функция должна делать.
Перед закрывающей фигурной скобкой мы видим команду return. Именно эта команда и отвечает за то, чтобы вернуть значение из функции. Т.е. смотрите, если программа дошла до этого места, то значит всё было хорошо и никаких ошибок не возникло, а значит можно вернуть значение нуль.
Вот мы и разобрались с функцией main. Ещё один момент. То что записано в фигурных скобках обычно называют «тело функции» (или описание функции), а первую часть, та что перед фигурными скобками называется заголовок функции.
Вернёмся теперь к нашей первой программе «Hello, World» и посмотрим, что там к чему.
Листинг 5. Программа «Hello, World»
Кое-что нам теперь уже понятно в этой программе. Не ясными остаются только две строки, пойдём по порядку.
Листинг 6. Директива include
Данная строчка это сообщение компилятору. Такие сообщения, начинающиеся с символа #, называются директивами компилятора. Буквально: «подключи файл stdio.h». Во время компиляции вместо этой строчки вставится содержимое файла stdio.h. Теперь немного поговорим об этом файле. stdio.h (от англ. STanDart Input Output) это заголовочный файл, в нем описаны различные стандартные функции, связанные с вводом и выводом.
Возникает резонный вопрос «А зачем нам писать эту строчку? Зачем нам вообще понадобилось вставлять сюда этот файл?» Это нужно для того, что бы в своей программе, мы могли использовать стандартную функцию вывода на экран printf().
Дело вот в чем. Прежде чем использовать что-нибудь в своей программе, нам надо сначала это описать. Представьте ситуацию, вас попросили принести канделябр, а вы знать не знаете что это такое. Непонятно, что делать.
Так же и компилятор. Когда он встречает какую-нибудь функцию, он ищет её описание (т.е. что она должна делать и что обозначает) в начале программы (с самого начала и до момента её использования в программе). Так вот, функция printf() описана в файле stdio.h. Поэтому мы и подключаем его. А вот когда мы его подключим, компилятор сможет найти функцию printf(), иначе он выдаст ошибку.
Кстати, настало время дополнить нашу карту знаний. Перед функцией main добавим ещё один блок, блок подключения заголовочных файлов.
Рис.3 Карта «Структура программ на языке Си.» Блок подключения заголовочных файлов.
Продолжим разбираться с нашей программой.
Листинг 7. функция printf()
Кстати, обратите внимание, каждая команда языка Си заканчивается символом «;» (точкой с запятой). Это похоже на точку в конце предложения, в русском языке. В обычном языке мы разделяем точкой предложения, а в языке программирования Си, точкой с запятой отделяем команды друг от друга. Поэтому ставить точку с запятой обязательно. Иначе компилятор будет ругаться и выдаст ошибку.
Чтобы вызвать какую-нибудь функцию, необходимо написать её имя и указать передаваемые ей параметры в круглых скобках. У функции может быть один или несколько параметров. А может не быть параметров вовсе, в таком случае в скобках писать ничего не нужно. Например, выше мы вызвали функцию printf() и передали ей один параметр строку, которую необходимо вывести на экран.
Кстати, полезный совет. Так как в каждой программе обязательно присутствует функция main, и буквально в каждой программе нам потребуется что-то выводить на экран, то рекомендую вам сразу создать файл со следующей заготовкой, чтобы каждый раз не писать одно и то же.
Листинг 8. Стандартная заготовка для программ на языке Си.
Ну вот вроде бы и всё. Этом первый урок можно считать законченным. Хотя нет, ещё один момент есть.
Самое главное в этом уроке это, конечно, общая структура программы. Но кроме того, мы научились выводить на экран произвольный текст. Кажется, что совсем ничего вроде и не узнали, но даже этого хватит для того, чтобы, например, сделать небольшой подарок своей маме на 8 марта.
Рис.4 Программа-открытка на 8 марта.
Исходный код программы-открытки есть в архиве с исходными кодами этого урока. Экспериментируйте! У вас всё получится.
Практика
Задачи с автоматической проверкой решения. Для удобства работы сразу переходите в полноэкранный режим
Исследовательские задачи для хакеров: