Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции_Программирование_Тема7,8,9,10,11_функции...doc
Скачиваний:
4
Добавлен:
14.08.2019
Размер:
73.22 Кб
Скачать

3

Лекции по дисциплине «Программирование»

Автор – Шульга Т.Э.

Тема 7Основы модульного программирования. Процедуры и функции

Одной из распространенных методик создания программной продукции в настоящее время является структурное программирование. Одним из основных принципов структурного программирования является принцип модульности. В соответствии с этим принципом программа разделяется на отдельные законченные фрагменты - модули, блоки которые просты по управлению и допускают независимую отладку и тестирование. В результате отдельные ветви программы могут создаваться разными группами программистов. (Следует заметить, что понятие «модуль» не совпадает в данном случае с понятием «модуль» в смысле «библиотека» языка Паскаль).

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

  • программа должна разделяться на независимые части, называемые модулями;

  • модуль - это независимый блок, код (текст) которого физически и логически отделен от кода других модулей;

  • модуль выполняет только одну логическую функцию, иначе говоря, должен решать самостоятельную задачу своего уровня по принципу: один программный модуль - одна логическая функция;

  • работа программного модуля не должна зависеть:

  • от входных данных;

  • от того, какому программному модулю предназначены его выходные данные;

  • от предыстории вызовов программного модуля;

  • размер программного модуля желательно ограничивать одной - двумя страницами исходного листинга (50-100 строк исходного кода);

  • модуль должен иметь только одну входную и одну выходную точку;

  • взаимосвязи между модулями устанавливаются по иерархической структуре;

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

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

  • в тексте модуля необходимо использовать комментарии, в особенности в сложных местах алгоритма;

  • идентификаторы переменных и модулей должны быть смысловыми, «говорящими»;

  • в одной строке стоит записывать не более одного оператора. Если для записи оператора требуется больше, чем одна строка, то все последующие операторы записываются с отступами;

  • желательно не допускать вложенности блоков операторов более трех уровней;

  • следует избегать использования языковых конструкций с неочевидной семантикой и программистских «трюков».

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

Подпрограммы

Простейшим видом модуля является подпрограмма.

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

Использование подпрограмм позволяет решить следующие задачи:

  • избавляет от необходимости многократно повторять в тексте программы аналогичные фрагменты;

  • улучшает читабельность текста программы, позволяя легче выявить ее логическую структуру и скрывая подробности вычислений (то есть повышается слепень абстрагирования);

  • повышают устойчивость к ошибкам программирования и непредвидимым последствиям при модификациях программы;

  • в общем случае уменьшает объем используемой памяти ЭВМ;

  • сокращает время отладки программы;

Существует два основных критерия создания подпрограммы.

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

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

  • если программа длинная: очевидно, что объем незначительно увеличится, но сама программа станет более читабельной. (Это примерно похоже на программы дисциплины на темы).

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

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

Все подпрограммы имеют следующие свойства:

  1. Обмен данными между подпрограммами осуществляется чаще всего через так называемый механизм передачи параметров (аргументов). (Аналог аргументов математической функции)

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

  3. Главной называется программа (подпрограмма), которая вызывается операционной системой.

  4. После выполнения операторов подпрограммы управление передается на оператор программы, вызвавшей данную подпрограмму, следующий за вызовом.

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

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

Тема 8

Тема 9Особенности написания и использования функций в языке С++

Объявление и определение функций в языке С++

В С++ понятия процедуры нет, существует только понятие функции. Если не требуется после выполнения последовательности операторов возвращать какое-либо значение, то функция имеет тип void. Функции (кроме функций имеющих тип void), могут использоваться во всех случаях, что и переменные, за исключением левой части оператора присваивания.

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

Таким образом, схема описания функций в программе на языке C++ представляется следующими двумя способами

1.

объявление функции f1

….

объявление функции fn

определение главной функции main

определение функции f1

…..

определение функции fn

Причем любая из функций fi может быть вызвана любой функцией fj и функцией main

2.

определение функции f1

…..

определение функции fn

определение главной функции main

Причем любая из функций fi может быть вызвана функцией fj, где j>=i и функцией main

Выбор одного из способов во многом определяется стилем написания программ конкретного программиста.

Синтаксис определения функции в языке С++:

[класс памяти] тип имя_функции ([список параметров]) [throw (исключения)]

{тело функции}

Класс памяти функции задает область действия функции. Для задания класса памяти допустимы только спецификаторы extern и static. Static указывает на то, что область действия функции с момента объявления и до конца файла, где она объявлена, extern - на то, что область действия функции во всех модулях, где она объявлена. По умолчанию – static.

Тип функции может быть любым кроме массива и функции (но может быть указателем на массив или функцию), может быть void.

Список параметров определяет величины, которые требуется передать в функцию при ее вызове. Элементы списка параметров разделяются запятыми. Для каждого параметра указывается тип и имя (в объявлении имя не обязательно). Параметры, перечисляемые в заголовке функции называются формальными, а параметры, записанные в операторе вызова функции, называются фактическими. В объявлении и определении одной функции типы и порядок следования параметров должны совпадать.

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

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

Функция возвращает значение с помощью оператора

return выражение; или return;.

Выражение в операторе return должно иметь тот же тип что и тип функции. Если функция имеет тип void, то этот оператор можно опустить

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

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

Последовательность фактических параметров в вызове функции и их тип должны точно совпадать с формальными параметрами этой функции

Существуют два способа передачи параметров в функцию – по значению и по адресу.

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

Например, функция, вычисляющая x в степени y.

int pow (int, int);

void main ()

{

cout<<pow(3,3);

getch();

}

int pow (int x, int y)

{

if (!y) return 1;

if (y>0)

{

int p=x;

for (int i=1; i<y; i++) p*=x;

return p;

}

int p=1/x;

for (int i=1; i<y; i++) p/=x;

return p;

}

При передаче по адресу в стек заносится копии адресов параметров, а следовательно функция может изменить содержимое участок памяти с этими адресами.

Например, функция вычисляющая сумму элементов массива

int Sum(int *mas, int n)

{

int summ=0;

for (int i=0; i<n; i++)

summ+=mas[i];

return summ;

}

void main()

{

const int n=3;

int r[n];

randomize();

for (int i=0; i<n; i++)

{

r[i]=random(6);

cout<<" "<<r[i];

}

cout<<"\nSum = "<<Sum(r, n);

getch();

}

Если требуется запретить изменение параметра внутри функции, то используется модификатор const.