Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Информатика_УчебноеПособие.doc
Скачиваний:
44
Добавлен:
03.05.2015
Размер:
862.21 Кб
Скачать

Проблема обмена информацией (данными) между функциями.

Объект, определенный в программе, обладает двумя свойствами.

Это:

- «время жизни» объекта– это время, в течение которого система гарантирует сохранность информации, записанной в его области памяти;

- «область видимости» объекта– это область программы, в которой информация в памяти объекта доступна для обработки (для чтения и изменения).

Программа состоит из отдельных объектов – функций. Каждая функция – это независимая область памяти. Блок задается фигурными скобками { }. Тело функции ограничено блоком.

Если объект–данное определен в блоке, то такой объект называется локальным объектом.

Локальныйобъект «живет» в блоке, то есть записанная в нем информация не будет разрушена, пока блок активен, то есть выполняются его инструкции. Локальный объект, определенный в блоке «жив», но может быть не виден в нем.

Локальныйобъект «виден» в блоке, то есть информация, записанная в нем, доступна для обработки, только в области памяти этого блокаот точки определения объектав инструкции его определениядо конца блока, в котором он определен.

В этой функции fun«живут» локальные объектыa, b (два объекта), c, x.

Объект aопределен в параметре, который получен по значению. Его область видимости – все тело функцииfun.

Объект b, определенный в параметре, получен по значению. Его область видимости – все тело функцииfun, кроме области вложенного блока (желтое пространство).

В этом блоке определен другой объект с именем b.Этот объект «живет» в этомвложенном блоке. Его область видимости от точки определения до скобки, закрывающей этот блок. Этот объектbзакрывает в этом месте объектb, определенный в параметре. Объектb, определенный в параметрах функцииfun, во вложенном блоке «жив», информация в нем не испорчена, но не доступна.

Обратите внимание, что в инструкции return x + b; виден и используется тот объектb, который определен в параметрах.

Объект хсоздан в инструкции определенияfloat x;. Его область видимости от этой точки определения до конца блока, ограничивающее тело функцииfun.

В инструкции-выражении x = (a * b + c); не правомерно использован объектc. Он «живет» и виден вовнутреннем блокефункции.

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

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

Есть несколько способов такого обмена информацией. Изучим эти способы.

Передача информации в функцию через параметры по значению. Возврат значения одного результата из функции через возвращаемое значение.

Этот механизм обмена информацией заложен в самом синтаксисе определения объекта типа функции:

тип_возвращаемого_значения имя_объекта_функции (список_формальных_параметров )

{

/* Здесь пишутся инструкции, которые определяют объекты, создаваемые внутри функции – локальные объекты.

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

*/

// инструкция return вернет значение-результат в точку вызова этой функции

// этот результат надо будет « поймать» (сохранить) в точке вызова

// иначе он будет потерян

return выражение;

}

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

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

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

тип_возвращаемого_значения - это тип того значения, которое будет одним из результатов работы функции и которое вернет инструкция return выражение; в точку вызова функции.

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

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

имя_вызываемой_функции (список_фактических_параметров )

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

Рассмотрим пример1.

Составить функцию countX, которая, получива, b ис через параметры по значению, вычисляетхи возвращает результат его вычисления через возвращаемое значение.

Вфункцииmainнеобходимо ввести значенияa, , . Используя функциюcountX, вычислить значениеX

и выдать его на экран.

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

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

float а

float b float

float c

Заголовок функции countX должен быть таким:

float countX (float a, float b, float c )

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

Описания (прототипы) этих функций находятся в хэдерном файле math.h. Для того чтобы воспользоваться этими функциями, необходимо подключить этот файл директивой #include к тексту разрабатываемой функции.

// Текст функции в файле example1.cpp

#include <math.h>

float countX (float a, float b, float c )

{

float x;

x = (a * cos(b + c) - b * sin(a + c)) / (pow(a,3) + b * b);

return x;

}

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

Попытка этот текст выполнить, приводит на этапе редактирования (линковки! LNK) к появлению сообщений.

Error 1 error LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup

Error 2 fatal error LNK1120: 1 unresolved externals

Это сообщения о том , что нет main!!! Без main программа не работает!

В функции main нужно вычислить результат как сумму 1 +а выр1 + 1 / выр2, где

выр1 можно вычислить с помощью разрабатываемой функции countX, если вместоа использовать значение , вместь b значение , а вместо c значение .

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

При решении задачи необходимо знать число pi. Эту константу можно задать самим, но грамотней воспользоваться стандартными математическими константами, которые заданы в хэдерном файле math.h

Имена констант

Вычисляемое

выражение

Значение константы

M_E

e

2.71828182845904523536

M_LOG2E

log2(e)

1.44269504088896340736

M_LOG10E

log10(e)

0.434294481903251827651

M_LN2

ln(2)

0.693147180559945309417

M_LN10

ln(10)

2.30258509299404568402

M_PI

pi

3.14159265358979323846

M_PI_2

pi/2

1.57079632679489661923

M_PI_4

pi/4

0.785398163397448309616

M_1_PI

1/pi

0.318309886183790671538

M_2_PI

2/pi

0.636619772367581343076

M_2_SQRTPI

2/sqrt(pi)

1.12837916709551257390

M_SQRT2

sqrt(2)

1.41421356237309504880

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

#define _USE_MATH_DEFINES

#include <math.h>

// Добавили в файл example1.cpp функцию main

#define _USE_MATH_DEFINES

#include <math.h>

#include <iostream>

#include <conio.h>

using namespace std;

float countX (float a, float b, float c )

{

float x;

x= (a * cos(b + c) - b * sin(a + c)) / (pow(a,3) + b * b);

return x;

}

void main ( void )

{

сout << endl << "vvedite a, x1, x2 "; // вывод строки-подсказки

float x1, a, x2; // порядок перечисления имен объектов

// в инструкции их определения любой

cin>>a>>x1>>x2; // в инструкции-выражении порядок перечисления

// имен объектов тот, что указан в строке-подсказке

float vir1;

vir1 = countX ( x1*x1, x2, M_PI_2);

float vir2;

vir2 = countX( x2, x1 + 1.2, 0);

float x = 1./11 + a * vir1 + 1 / vir2; // обратите внимание 1./11, а не 1/11

cout << endl << "X = " << x;

getch();

}

Так выглядит ввод и вывод на экране при работе программы.

Пояснения к работе программы.

Программа начинает работать с функции main.

Первая исполняемая инструкция-выражение

сout << endl << "vvedite a, x1, x2 ";

выводит на экран подсказку.

Следующая инструкция-выражение вводит информацию с клавиатуры в три объекта a, x1, x2. Пользователь ввел a равное 1, x1 равное 2, x2 равное 3.

В инструкции-выражении

vir1 = countX ( x1*x1, x2, M_PI_2);

первым выполняется оператор ( ) вызова функции.

При вызове функции countX эта функция принимает первый фактический параметр по значению ( получает результат вычисления выраженияx1*x1, равное4) и для хранения этого значения4в объекте–функцииcountX создается локальный объект с именема, тип которогоfloat(т.к. первый формальный параметр в списке формальных параметров функцииfloat a). Полученное через параметр значение 4 записывается в этот локальный объект а. Так же передаются остальные два фактических параметра – значения 3 из объекта x2 и 1.57 из константы M_PI_2. Для записи этих значений создаются локальные объекты b и c. Значения, записанные в локальные объекты а,b и c используются при вычислении значения результата 0.02 в локальном объекте х функции countX. Этот результат инструкциейreturn x; возвращается в точку вызова функции countX в объектеmain, когда функция countX заканчивает работу и передает управление снова в функциюmain.

Последним в выражении

vir1 = countX ( x1*x1, x2, M_PI_2)

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

Значение 0.02, которое возвращает функция countX, оператором присвоить = копируется в область локального объекта vir1 функции main.

Все локальные объекты, определенные в функции countX, «живы», пока функция выполняет работу. ФункцияcountXзакончила работу, его локальные объекты «умерли» вместе с функцией.

При втором вызове функции countX в инструкции-выражении

vir2 = countX( x2, x1 + 1.2, 0);

первым выполняется оператор () вызова функции countX.

Эта функция получает первый фактический параметр по значению ( получает значение3). Для хранения этого значения3в объекте–функции вновь создается локальный объекта, тип которогоfloat(т.к. первый формальный параметр в списке формальных параметров функцииfloat a). Полученное через параметр значение 3 записывается в этот локальный объект а. Так же передаются остальные два фактических параметра – значения 3.2 и 0, для них создаются локальные объекты b и c. Эти значения используются при вычислении значения -0.09 объекта х в функции countX, которое инструкциейreturn x; возвращается в точку вызова функции countX в объектеmain для продолжения вычисления выражения:

vir2 = countX( x2, x1 + 1.2, 0)

Последним в этом выражении выполняется оператор присвоить =, который копирует в область локального объекта vir2 функции main то значение -0.09, которое вернула функция countX.

Выполняется инструкция определения объекта:

float x = 1./11 + a * vir1 + 1 / vir2;

Созданный этим оператором объект х, при создании инициализируется значением, вычисленным в выражении 1./11 + a * vir1 + 1 / vir2, тип которого float.

Обратите внимание, что значение выражения 1/11, будучи вычисленым, равно 0, его тип int, так как оба операнда этого выражения имеют тип int. А значение выражения 1./11 имеет тип float, так как один из операндов этого выражения, а именно 1. имеет тип float, поэтому результат получают в кодировке float и он равен 0.090909(смотрите неявное преобразование типов!).

Инструкции-выражения

cout << endl << "X = " << x;

getch();

организуют вывод результата на экран и задержку.