Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Структура программы на языке С.docx
Скачиваний:
0
Добавлен:
01.03.2025
Размер:
112.31 Кб
Скачать

Структура программы на языке С++. Выглядит схема примерно так: Подключаемые внешние файлы (*.h, *.cpp) Обьявление глобальных переменных и функций int main(список аргументов) { последовательность операторов } тип_возвращаемого_значения имя_функции (список входных параметров) { последовательность операторов } Этой схеме можно привести простейший пример на C++: #include <stdio.h> int main(int argc, char* argv[]) { // тело функции return 0; } int& min(int& a, int& b) { if (a>b) return a; return b; } Программа на языке С++ может состоять из одной и более функций, но функция ... main( ... ) должна быть только одна. Именно с этой функции начинается выполнение программы, поэтому, при отсутствии ( или в наличии более чем один экземпляр ) такой функции компилятор выдаст соответствующее сообщение об ошибке. Еще такое замечание, в С и С++ любая последовательность операторов заканчивается ';' - символом точка с запятой, поэтому будьте внимательны, когда набираете программу, если забудете поставить - компилятор выдаст сообщение об ошибке: в строке такой то нехватает символа ';'. Комментарии в программе пишутся после " // " или между " /* ... */ ". В первом случае их размер не должен превышать размера строки, во втором размер неограничен.

Типы данных языка С++. В С++ несколько базовых типов данных: int - целые числа, float - с плавающей точкой, double- двойной точности, char - символьные данные, void - без значения, bool - булевская переменная, принимает значениея true или false, complex - комплексные числа. На основе этих типов и формируются другие типы данных. Эти формирования происходят несколькими путями, в частности с помощью спецификаторов типов: signed - знаковый, unsigned - беззнаковый, long - длинный, short - короткий. К примеру: signed char, unsigned int, short int,long double, unsigned long float ... В С++ имеются такие типы данных, аналоги которых имеют не все языки программирования, в частности это ссылки и указатели. Их мы рассмотрим немного позднее.

Переменные. Переменная - это контейнер, в котором хранятся какие-то данные. Переменная имеет два основных свойства - это имя или идентификатор и тип. Имя переменной должно начинаться с символа латинского алфaвита "a, ..., z" или символа подчеркивания '_', и содержит цифры, символы или еще символы подчеркивания '_'. К примеру: Count, _string, Mode_1; Запомните, прежде чем использовать в своей программе какую-то переменную, её сначало необходимо обьявить. Делается это так: тип_переменной_(ых) список_имен; На С++ это выглядит так: int i, j, k; short int si; unsigned int ui; double balance, profit, loss; Обьявлять переменные возможно в трех местах: внутри функции, в определении параметров функции и вне всех функций. Это соответственно места обьявления локальных переменных, формальных параметров функции и глобальных переменных. Локальные перменные можно использовать только внутри блока, в котором они обьявлены. Например: #include <stdio.h> int main(void) { int x; x=10; double f; if(x==10) { int x; // эта х прячет внешнюю х x=99; printf("Внутренняя: %d",x); } printf("Внешняя: %d",x); // f здесь недоступна return 0; } // f здесь недоступна Результат выполнения программы: Внутренняя: 99 Внешняя: 10 Если функция имеет аргументы, значит должны быть обьявлены переменные, которые примут их значения. Эти переменный носят название формальные параметры и фигурируют внутри функции как обычные локальные переменные. Глобальные переменные могут использоваться влюбом месте программы, они сохранают свое значение на протяжении все работы программы.

Прежде чем приступить к написанию программ, необходимо изучить структуру программ  на языке программирования С++. Структура программ С++ это разметка рабочей области (области кода) с целью чёткого определения основных блоков программ и синтаксиса. Структура программ несколько отличается в зависимости от среды программирования. Мы ориентируемся на MVS2010, и по этому примеры программ будут показаны именно для MVS2010. Нет ничего сложного в том, чтобы портировать код из MVS2010 в другие среды разработки и вы поймете со временем, как это сделать.  

Структура программ С++ для Microsoft Visual Studio.

?

1

2

3

4

5

6

// struct_program.cpp: определяет точку входа для консольного приложения.

#include "stdafx.h" 

//здесь подключаем все необходимые препроцессорные директивы

void main() { // начало главной функции с именем main

//здесь будет находится ваш программный код

}

В строке 1 говорится о точке входа для консольного приложения, это значит, что данную программу можно запустить через командную строку Windows указав имя программы, к примеру, такое struct_program.cppСтрока 1 является однострочным комментарием, так как начинается с символов "//", подробнее о комментариях будет рассказано в следующей статье. В строке 2 подключен заголовочный файл "stdafx.h". Данный файл похож на контейнер, так как в нем подключены основные препроцессорные директивы(те, что подключил компилятор, при создании консольного приложения), тут же могут быть подключены и вспомогательные(подключенные программистом).

include - директива препроцессора, т. е. сообщение препроцессору. Строки, начинающиеся с символа "#" обрабатываются препроцессором до компиляции программы.

Препроцессорные директивы также можно подключать и в строках, начиная после записи #include "stdafx.h" до начала главной функции. Причём такой способ подключения библиотек является основным, а использование "stdafx.h" - это дополнительная возможность подключения заголовочных файлов. С 4-й по 6-ю строки объявлена функция main. Строка 4 – это заголовок функции, который состоит из типа возвращаемых данных (в данном случае void), этой функцией, и имени функции, а также круглых скобочках, в которых объявляются параметры функции.

void - тип данных не имеющий значения, т.е он не может хранить никакой информации.

Между фигурными скобочками  размещается  основной программный код, называемый еще телом функции. Это самая простая структура программы. Данная структура написана в Microsoft Visual Studio 2010(MVS2010). Все выше сказанное остается справедливым и для других компиляторов,  кроме строки 2. Контейнера "stdafx.h" нигде кроме MVS нет.

Структура программы для  C++ Builder.

При создании консольного приложения мастер создания проектов создает автоматически следующий код:

?

1

2

3

4

5

6

//препроцессорная директива, автоматически подключённая мастером создания  проектов

#include <vcl.h> 

int main()

{

return 0;

}

Мы видим, что у функции поменялся тип данных, место void написано int. Это говорит о том что по завершении работы функция вернет какое-то целочисленное значение, в нашем случае 0. Целочисленное потому, что int – это тип данных для целых чисел, таких как  4,  5,  6,  456, 233 и т. д.

Главное помнить, что если тип возвращаемых данных у функции main - int или любой другой, кроме void, то следует писать строку типа этой: return  возвращаемое значение;

В строке 2 подключена библиотека vcl.h  – её генерит мастер создания приложений автоматически, поэтому удалять её не следует, иначе проект не будет рабочим.

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

Например:

?

1

2

3

4

int main(int argc, char* argv[])

{

return 0;

}

Такой пример структуры генерится мастером в MVS2010. Данный main немного отличается. Подробнее рассмотрим позже, но скажу, что данный main имеет такой вид, так как изначально рассчитан на поддержку юникода. Юникод - стандарт кодирования символов, позволяющий представить знаки практически всех письменных языков. Подробнее о юникоде поговорим позже.

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

Пример структуры программы MVS2010 с подключенными библиотеками.

?

1

2

3

4

5

6

#include "stdafx.h"

#include <iostream>

using namespace std;

void main()

{

}

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

Заголовочные файлы и имя подключаемых библиотек – одно и то же.

Синтаксис подключения заголовочных файлов:

#include <имя заголовочного файла>

Более старые заголовочные файлы подключаются так (этот стиль подключения библиотек унаследован у языка программирования C):

#include <имя заголовочного файла.h>

Различие состоит в том, что после имени ставится расширение  ".h".

Язык программирования С++ является регистрозависимым. Например: Return 0; – не правильно, будет ошибка компиляции. return 0; – правильно!!!

1.1. Структура и этапы создания программы на языке С++

Сама по себе программа на языке С++ представляет собой текстовый файл, в котором представлены конструкции и операторы данного языка в заданном программистом порядке. В самом простом случае этот текстовый файл может содержать такую информацию: Листинг 1.1. Пример простой программы. /* Пример простой программы*/ #include int main() { printf(“Hello World!”); return 0; }

и обычно имеет расширение cpp, например, «ex1.cpp».

Следующий шаг – это компиляция исходного кода. Под компиляцией понимают процесс, при котором содержимое текстового файла преобразуется в исполняемый машинный код, понимаемый процессором компьютера. Однако компилятор создает не готовую к исполнению программу, а только объектный код (файл с расширением *.obj). Этот код является промежуточным этапом при создании готовой программы. Дело в том, что создаваемая программа может содержать функции стандартных библиотек языка С++, реализации которых описаны в объектных файлах библиотек. Например, в приведенной программе используется функция printf() стандартной библиотеки «stdio.h». Это означает, что объектный файл ex1.obj будет содержать лишь инструкции по вызову данной функции, но код самой функции в нем будет отсутствовать.

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

Рассмотрим более подробно пример программы листинга 1.1. Первая строка задает комментарии, т.е. замечания, помогающие лучше понять программу. Они предназначены только для чтения и игнорируются компилятором. Во второй строке записана директива #include, которая дает команду препроцессору языка С++ вставить содержимое файла ‘stdio.h’ на место этой строки при компиляции. В третьей строке определена функция с именем main, которая возвращает целое число (тип int) и не принимает никаких аргументов (тип void). Функция main() является обязательной функцией для всех программ на языке С++ и без ее наличия уже на этапе компиляции появляется сообщение об ошибке, указывающее на отсутствие данной функции. Обязательность данной функции обусловливается тем, что она является точкой входа в программу. В данном случае под точкой входа понимается функция, с которой начинается и которой заканчивается работа программы. Например, при запуске exe-файла происходит активизация функции main(), выполнение всех операторов, входящих в нее и завершение программы. Таким образом, логика всей программы заключена в этой функции. В приведенном примере при вызове функции main() происходит вызов функции printf(), которая выводит на экран монитора сообщение “Hello World!”, а затем выполняется оператор return, который возвращает нулевое значение. Это число возвращается самой функцией main() операционной системе и означает успешное завершение программы. Фигурные скобки {} служат для определения начала и конца тела функции, т.е. в них содержатся все возможные операторы, которые описывают работу данной функции. Следует отметить, что после каждого оператора в языке С++ ставится символ ‘;’. Таким образом, приведенный пример показывает общую структуру программ на языке С++.

1.3. Представление данных в языке С++

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

Для того чтобы иметь возможность работать с тем или иным типом данных необходимо задать переменную соответствующего типа. Это осуществляется с использованием следующего синтаксиса:

<тип переменной> <имя_переменной>;

например, строка

int arg;

объявлет целочисленную переменную с именем arg.

Основные базовые типы данных:

int - целочисленный тип 16 либо 32 бит

long int - целочисленный тип 32 бит

short - целочисленный тип 8 либо 16 бит

char - символьный тип 8 бит

float - вещественный тип 32 бит

double - вещественный тип 64 бит

Отметим, что при выборе имени переменной целесообразно использовать осмысленные имена. При определении имени можно использовать как верхний, так и нижний регистры букв латинского алфавита. Причем первым символом обязательно должна быть буква или символ подчеркивания ‘_’.

В приведенных примерах переменные arg и Arg считаются разными, т.к. язык С++ при объявлении переменных различает большой и малый регистры.

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

Для того чтобы задать то или иное значение переменной используется оператор присваивания, который записывается как знак ‘=’. Работу этого оператора представим на следующем примере:

int length = 5;

Здесь переменной с именем length присваивается значение 5, т.е. элемент слева от знака равенства является именем переменной, а элемент справа – это значение, присвоенное этой переменной. Сам символ ‘=’ называется оператором присваивания.

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

int i=2; i=i+1;

С математической точки зрения такая операция не имеет смысла, т.к. переменная i не может быть равна i+1. Однако данная запись в смысле операции присваивания вполне приемлема. Действительно, компьютер сначала определит значение переменной i, а затем прибавит 1 к этому значению и полученный результат присвоит снова переменной i. Таким образом, исходное значение переменной i увеличится на 1.

Так как оператор присваивания задает значение переменной, то оператор типа

20 = i;

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

Теперь рассмотрим такой пример. Допустим, что имеются две переменные разного типа:

short agr_short = -10; long arg_long;

и выполняется оператор присваивания

arg_long = arg_short;

В результате переменная arg_long будет иметь значение 10 и оператор присваивания выполнит автоматическое преобразование типов и потери данных не происходит. В другом случае, когда

float agr_f = 8.7; int arg_long; arg_long = arg_f;

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

<имя_переменной_1> = (тип_данных)<имя_переменной_2>;

Например,

arg_long = (long )arg_f;

Операторы языка C++

Операторы управляют процессом выполнения программы. Набор операторов языка С++ содержит все управляющие конструкции структурного программирования.

Составной оператор ограничивается фигурными скобками. Все другие операторы заканчиваются точкой с запятой.

  • Пустой оператор – ;

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

  • Составной оператор – {...}

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

  • Оператор обработки исключений try { <операторы> }

  • catch (<объявление исключения>) { <операторы> }

  • catch (<объявление исключения>) { <операторы> }

  • ...

  • catch (<объявление исключения>) { <операторы> }

  • Условный оператор if (<выражение>) <оператор 1> [else <оператор 2>]

  • Оператор-переключатель switch (<выражение>)

  • { case <константное выражение 1>: <операторы 1>

  • case <константное выражение 2>: <операторы 2>

  • ...

  • case <константное выражение N>: <операторы N>

  • [default: <операторы>]

  • }

Оператор-переключатель предназначен для выбора одного из нескольких альтернативных путей выполнения программы. Вычисление оператора-переключателя начинается с вычисления выражения, после чего управление передается оператору, помеченному константным выражением, равным вычисленному значению выражения. Выход из оператора-переключателя осуществляется оператором break. Если значение выражения не равно ни одному константному выражению, то управление передается оператору, помеченному ключевым словом default, если он есть.

  • Оператор цикла с предусловием while (<выражение>) <оператор>

  • Оператор цикла с постусловием do <оператор> while <выражение>;

В языке C++ этот оператор отличается от классической реализации цикла с постусловием тем, что при истинности выражения происходит продолжение работы цикла, а не выход из цикла.

  • Оператор пошагового цикла for ([<начальное выражение>];

  • [<условное выражение>];

  • [<выражение приращения>])

  • <оператор>

Тело оператора for выполняется до тех пор, пока условное выражение не станет ложным (равным 0). Начальное выражение и выражение приращения обычно используются для инициализации и модификации параметров цикла и других значений. Начальное выражение вычисляется один раз до первой проверки условного выражения, а выражение приращения вычисляется после каждого выполнения оператора. Любое из трех выражений заголовка цикла, и даже все три могут быть опущены (не забывайте только оставлять точки с запятой). Если опущено условное выражение, то оно считается истинным, и цикл становится бесконечным.

Оператор пошагового цикла в языке С++ является гибкой и удобной конструкцией, поэтому оператор цикла с предусловием while используется в языке С++ крайне редко, т.к. в большинстве случаев удобнее пользоваться оператором for.

  • Оператор разрыва break;

Оператор разрыва прерывает выполнение операторов while, do, for и switch. Он может содержаться только в теле этих операторов. Управление передается оператору программы, следующему за прерванным. Если оператор разрыва записан внутри вложенных операторов while, do, for, switch, то он завершает только непосредственно охватывающий его оператор.

  • Оператор продолжения continue;

Оператор продолжения передает управление на следующую итерацию в операторах цикла while, do, for. Он может содержаться только в теле этих операторов. В операторах do и while следующая итерация начинается с вычисления условного выражения. В операторе for следующая итерация начинается с вычисления выражения приращения, а затем происходит вычисление условного выражения.

  • Оператор возврата return [<выражение>];

Оператора возврата заканчивает выполнение функции, в которой он содержится, и возвращает управление в вызывающую функцию. Управление передается в точку вызывающей функции, непосредственно следующую за оператором вызова. Значение выражения, если она задано, вычисляется, приводится к типу, объявленному для функции, содержащей оператор возврата, и возвращается в вызывающую функцию. Если выражение опущено, то возвращаемое функцией значение не определено.

С формальной точки зрения операторы break, continue и return не являются операторами структурного программирования. Однако их использование в ограниченных количествах оправдано, когда они упрощают понимание программы и позволяют избегать больших вложенных структур. Например, мы проверяем входные данные на аномалии. Если не использовать эти операторы, то всю обработку придется вложить в условный блок, что ухудшает читабельность программы. Вместо этого можно написать небольшой условный блок, который организует выход из функции при неверных исходных данных.

Ввод/вывод не является частью языка С++, а осуществляется функциями, входящими в состав стандартной библиотеки. Для подробной информации см. лекцию 4.

2. Структура программы

Программа на языке С++ состоит из директив препроцессора, указаний компилятору, объявлений переменных и/или констант, объявлений и определений функций.

2.1. Объявление переменной

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

Объявление переменной имеет следующий синтаксис:

[<спецификация класса памяти>] <тип> <имя> [= <инициализатор>]

[,<имя> [= <инициализатор>] ...];

Примеры объявления переменных

int x;

// Объявление переменной целого типа без инициализатора

double y = exp(1);

// Переменная вещественного типа инициализируется числом e.

// exp(x) – функция, вычисляющая ex.

int a, b = 0;

// Объявление двух переменных целого типа. Переменная b инициализируется значением 0.

В языке С++ нет ограничений на количество символов в имени. Однако некоторые части реализации (в частности, компоновщик) недоступны автору компилятора, и они иногда накладывают такие ограничения.

2.1.1. Константы

В языке С++ введена концепция определяемых пользователем констант для указания на то, что значение нельзя изменить непосредственно. Это может быть полезно в нескольких отношениях. Например, многие объекты не меняются после инициализации; использование символических констант приводит к более удобному в сопровождении коду, чем применение литералов непосредственно в тексте программы; указатели часто используются только для чтения, но не для записи; большинство параметров функций читаются, но не перезаписываются.

Чтобы объявить объект константой, в объявление нужно добавить ключевое слово const. Так как константе нельзя присваивать значения, она должна быть инициализирована.

const int a = 100;

const int b[] = {1, 2, 3, 4, 5};

const int c;

// a является константой

// Все b[i] являются константами

// Ошибка – нет инициализатора!

Типичным является использование констант в качестве размера массивов и меток в инструкции case.

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

2.1.2. Объявление typedef

Объявление, начинающееся с ключевого слова typedef, вводит новое имя для типа, не для переменной данного типа. Целью такого объявления часто является назначение короткого синонима для часто используемого типа. Например, при частом применении unsigned char можно ввести синоним uchar.

typedef unsigned char uchar;

// Теперь uchar – синоним для unsigned char

Имена, вводимые с помощью typedef, являются синонимами, а не новыми типами. Следовательно, старые типы можно использовать совместно с их синонимами. Если вам нужны различные типы с одинаковой семантикой или с одинаковым представлением, обратитесь к перечислениям или классам.