Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
mlr_progr_1sem.doc
Скачиваний:
7
Добавлен:
03.11.2018
Размер:
1.72 Mб
Скачать

Контрольные вопросы

1) Как получить доступ к элементам массива?

2) Вы используете в программе двумерный массив размером 1000×1000. Вам необходимо провести начальную инициализацию элементов этого массива. Инициализация заключается в присвоении каждому элементу массива случайного значения. Ваши действия?

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

4) Приведите алгоритм решения любой из задач данной лабораторной работы кроме своего варианта.

Лабораторная работа №4

Цель: усовершенствовать навыки программирования на примерах создания и использования собственных функций.

Задачи:

1) Повторить теоретические сведения о создании и использовании статических массивов в языке Си++.

2) Разработать программу решающую одну из задач матричной алгебры.

Основные теоретические сведения. Функции

Функция в Си++ обеспечивает удобный способ отдельно оформить некоторое вычисление и пользоваться им далее, не заботясь о том, как оно реализовано. После того, как функции написаны, можно забыть, как они сделаны, достаточно знать лишь, что они умеют делать. Механизм использования функции в Си++ удобен, легок и эффективен. Нередко вы будете встречать короткие функции, вызываемые лишь единожды: они оформлены в виде функции с одной-единственной целью - получить более ясную программу.

До сих пор мы пользовались готовыми функциями вроде main, sin, sqrt и т.д. Теперь настала пора нам самим написать несколько функций. Проиллюстрируем механизм определения функции на примере функции mean(m, n), которая считает среднее арифметическое двух целых чисел m и n. Так, mean(2, 4) имеет значение 3.

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

а) б)

Рис. 16.

Реализация этих алгоритмов приведена в листинге 24.

Листинг 24

/* Тест функции mean */

#include <stdio.h>

double mean( int nArg1, int nArg2 ); // Объявление функции

int main( void ) // main тоже функция и может возвращать некий результат

{

int i;

for (i = 0; i < 10; i++ )

{

printf("mean(%d, %d)= %g\n", 2, i, mean( 2, i ));

}

return 0; // Традиционно, при корректном завершении

// функция main возвращает 0

}

/* Описание функции mean */

double mean( int nArg1, int nArg2 )

{

return double( nArg1 + nArg2 ) / 2;

}

Рассмотрим листинг 24 более подробно. Начнем со строки

double mean( int nArg1, int nArg2 );

Как и переменные, функции необходимо объявлять перед использованием.

В общем виде объявление функций осуществляется следующим образом:

Тип_результата Имя_функции ( список параметров, если он есть );

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

int i;

означает объявление перменнной i. В тоже время строка

int i();

означает объявление функции i().

Но вернемся к нашей программе. Строкой

double mean( int nArg1, int nArg2 );

мы говорим, что у нас в программе будет использоваться некая функция mean. Функция mean ожидает два аргумента типа int и возвращает результат типа double. Это объявление, называемое прототипом функции, должно быть согласовано с описанием (см. ниже) и всеми вызовами mean. Если объявление функции или вызов не соответствует своему прототипу, это ошибка.

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

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

Далее в листинге 19 следует уже традиционная функция main. Вы, вероятно, обратили внимание на инструкцию return в конце main. Поскольку main есть функция, как и любая другая она может вернуть результирующее значение тому, кто ее вызвал, - фактически в ту среду, из которой была запущена программа. Обычно возвращается нулевое значение, что говорит о нормальном завершении выполнения. Ненулевое значение сигнализирует о необычном или ошибочном завершении. До сих пор ради простоты мы считали, что функция main ничего не возвращает и объявляли ее как void main(), опуская инструкцию return внутри main.

Внутри main результат выполнения функции mean используется в качестве аргумента функции printf.

После функции main в листинге 19 следует описание функции mean.

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

Тип_результата Имя_функции (список параметров, если он есть)

{

объявления

инструкции

}

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

Значение, вычисляемое функцией mean, возвращается в main с помощью инструкции return. За словом return может следовать любое выражение:

return выражение;

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

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

Также возможны ситуации, когда вызывающая функция игнорирует возвращаемый ей результат. Существует множество стандартных функций которые возвращают специфическую информацию которая не всегда нужна. Вы уже неоднократно сталкивались с такой ситуацией. Это была функция printf(). Каждый вызов этой функции возвращает количество напечатаных символов. Но нам эта информация не нужна поэтому мы ее игнорируем.

Мы рассмотрели самый простой вариант оформления собственных функций в пределах одного файла. На самом деле современное программное обеспечение структурно состоит из множества файлов содержащих объявления и описания различных функций. Традиционно все объявления функций выносят в отдельные файлы-заголовки. Эти файлы можно рассматривать как собственные библиотеки функций и оперировать с ними соответствующим образом. Описание функций также оформляется в отдельных файлах-реализациях. Обычно файл-заголовок и файл-реализация имеют одинаковое имя и отличаются только расширением. У файла-заголовка расширение «*.h», у файла-реализации — «*.cpp».

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

Не смотря на то, что все работы данного лабораторного практикума достаточно просты и могут быть реализованы в пределах одной функции main, в дальнейшем будем их оформлять в рамках как минимум двух функций. При этом реализация функции main будет иметь вид представленный в листинге 25:

Листинг 25

/* В последующих лабораторных работах

функция main будет оформляться подобным образом */

#include “MyFunction.h”

int main( void )

{

MyFunction();

return 0;

}

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

Давайте перерь перепишем программу mean представленную в листинге 19 в соответствии с вышеизложенным.

Прежде всего, создайте пустой проект консольного типа, добавте в него cpp-файл, например main.cpp и напишите в нем реализацию функции main в соответствии с листингом 26.

Листинг 26

/* Модифицированный вариант оформления программы mean

файл main.cpp */

#include “mean.h”

#include <stdio.h>

int main( void )

{

int i;

for ( i = 0; i < 10; i++ )

{

printf( "mean(%d, %d)= %g\n", 2, i, mean( 2, i ));

}

return 0;

}

Теперь добавьте в проект h-файл. В меню выберите File ► New ► Files. В появившемся окне диалога (рис. 7 лабораторной работы №1) выберите C++ Header File.  Поставьте птичку «Add to project». В поле File name задайте имя mean и нажмите кнопку OK.

У вас появится на экране пустое окно «mean.h» для ввода программного кода. Введи в него код из листинга 27.

Листинг 27

/* Модифицированный вариант оформления программы mean

файл mean.h */

#ifndef __MEAN_

#define __MEAN_

double mean( int nArg1, int nArg2 );

#endif

Это листинг мы поясним чуть позже, а теперь добавте в проект еще идин cpp-файл (аналогично файлу main.cpp). Задайте ему тоже имя mean и введите код из листинга 28.

Листинг 28

/* Модифицированный вариант оформления программы mean

файл mean.cpp */

#include "mean.h"

double mean( int nArg1, int nArg2 )

{

return double( nArg1 + nArg2 ) / 2;

}

Теперь рабочее пространство вашего проекта будет похоже на рис. 17.

Рис. 17.

Можете откомпилировать и запустить программу.

Вернемся к листингу 27. Конструкция

#ifndef __MEAN_

#define __MEAN_

#endif

фактически означает следующее. Если не определено ключевое слово __MEAN_ (первая строка), то определить ключевое слово __MEAN_ (вторая строка) и выполнить весь код до дериктивы #endif.

Прежде всего следует отметить, что когда мы используем директиву #include … компилятор фактически подставляет в код программы содержимое указанного в директиве файла. Очевидно, что нет смысла включать один и тотже файл несколько раз. К томуже компилятор и не позволит это сделать. С целью оптимизации программного кода и используется конструкция приведенная выше. Ключевое слово (в нашем случае __MEAN_) — это уникальный идентификатор файла. Он может быть абсолютно любым. Обычно в качестве этого ключа используют имя файла с символами подчеркивания в начале и в конце имени, что именьшает вероятность возникновения такого же ключевого слова. Когда компилятор впервые подключает файл соответствующее ключевое слово еще не определено и результат проверки условия в директиве #ifndef (если не определено) есть истина. Поэтому выполняется код следующий за дериктивой #ifndef, а это прежде всего директива #define (определить). Именно в ней и определяется ключевое слово. Теперь когда компилятор повторно встретит директиву #include с уже подключенным файлом-заголовком, результат проверки условия в директиве #ifndef будет ложь и весь код вплоть до директивы #endif будет пригнорирован.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]