Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Практическая работа №6. Функции программиста и подключение сторонних библиотек. Работа с модулями

Поиск

Цель работы: изучение принципов работы с функциями в С++.

 

Задачи:

1. Изучить теоретический материал

2. Написать программу согласно индивидуальному варианту задания.

3. Ответить на контрольные вопросы.

4. Оформить отчет.

 

Теоретический материал

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

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

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

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

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

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

Рассмотрим составные части определения.

· Необязательный класс памяти: extern – задает глобальную видимость во всех модулях программы (по умолчанию), static – задает видимость только в пределах модуля, в котором определена функция.

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

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

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

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

#include <iostream.h>

int sum(int a, int b); // Объявление функции

int main() {

int a=2, b=3, c, d;

c = sum(a, b); //вызов функции

cin >> d;

cout << sum(c, d); //вызов функции

return 0;

}

int sum (int a, int b) { // Определение функции

return (a+b);

}

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

Определение функции с аргументом

Определение нашей функции начинается с двух строк:

space (number);

int number;

Первая строка информирует компилятор о том, что у функции space () имеется аргумент и что его имя number. Вторая строка — описание, указывающее компилятору, что аргумент number имеет тип int. Аргумент описывается перед фигурной скобкой, которая отмечает начало тела функции. Можно объединить эти две строки в одну:

space (int number);

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

Вызов функции с аргументом

Переменной number присваивается значение факти­ческого аргумента при вызове функции. Например, случай использования функции space ():

space (25):

Фактический аргумент здесь 25, и эта величина присваивается формальному аргументу — переменной number, т. е, вызов функции оказывает следующее действие:

number = 25;

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

Локальные переменные

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

Глобальные переменные

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

Нахождение адресов: операция &

В результате выполнения операции & определяется адрес ячейки памяти, которая соответствует переменной. Если p — имя пе­ременной, то & p — ее адрес. Можно представить себе адрес как ячейку памяти, но можно рассматривать его и как метку, кото­рая используется компьютером для идентификации переменной. Мы имеем оператор

p = 24;

Пусть также адрес ячейки, где размещается переменная p — 12126. Тогда в результате выполнения оператора

printf ("%d %d \n", p, &p);

получим 24 12126

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

// контроль адресов

main() {

int a = 2, b = 5;

printf(" В main(), a = %d и &a = %u\n", a, &a);

printf(" В main(), b = %d и &b = %u\n", b, &b);

fun(a);

}

fun(b)

int b;

{

int a = 10;

printf(" В fun(), a = %d и &a = %u\n", a, &a);

printf(" В fun(), b = %d и &b = %u\n", b, &b);

}

Мы воспользовались форматом % u (целое без знака) для вывода на печать адресов на тот случай, если их величины превысят макси­мально возможное значение числа типа int. В нашей вычислитель­ной системе результат работы этой программы выгля­дит так:

В main(), a = 2 и &a = 56002

В main(), b = 5 и &b = 56004

В fun (), a = 10 и &a = 55944

В fun (), b = 2 и &b = 56000

О чем это говорит? Во-первых, две переменные a имеют различные адреса. То же самое верно и относительно переменных b. Компьютер рассматрива­ет их как четыре разные переменные. Во-вторых, при вызове fun (a) величина (2) фактического аргумента (a из main ()) передается формальному аргументу (b из fun ()). Было передано только значение перемен­ной. Адреса двух переменных (a в main () и b в fun ()) остаются различными. В языке Си аргументы передаются по значению.

Возвращаемое значение

Механизм возврата из функции в вызвавшую ее функцию реализуется оператором

return [выражение];

Функция может содержать несколько операторов return (если это необходимо алгоритму функции). Если функция описана как void, выражение не указывается. Оператор return можно опускать для функции типа void, если возврат из нее происходит перед закрывающейся фигурной скобкой, и для функции main.

Параметры функции

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

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

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

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

Пример передачи параметров в функцию по значению.

// обмен1

main() {

int x = 5, у = 10;

printf(" Вначале x = %d и у = %d\n", x, у);

change(x, у);

printf(" Теперь x = %d и у = %d\n", x, у);

}

change(int u, int v) {

int temp;

temp = u;

u = v;

v = temp;

}

Результаты будут выгля­деть следующим образом:

Вначале х = 5 и у = 1 0

Теперь х = 5 и у = 10

Функции change () и main () используют различные переменные, поэто­му обмен значениями между переменными u и v не оказывает ника­кого влияния на х и у.

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

// обмен2

main() {

int х=5, у = 10;

printf(" Вначале x = %d и у = %d\n", x, у);

change(&x, &у); //передача адресов функции

printf(" Теперь x = %d и у = %d\n", x, у);

}change(int *u, int *v) { // u и v являются указателями

int temp;

temp = *u; //temp присваивается значение, на которое указывает u

*u = *v;

*v = temp;

}

Результат:

Вначале х = 5 и у = 10.

Теперь х = 10 и у = 5.

Во-первых, теперь вызов функ­ции выглядит следующим образом:

change (&x, &y);

Вместо передачи значении х и у мы передаем их адреса. Это озна­чает, что формальные аргументы u и v при обращении будут заменены адресами и, следовательно, они должны быть описаны как указатели. Поскольку x и у — целого типа, u и v являются указателями на переменные целого типа, и мы вводим описание int * u, int * v для описания формальных параметров функции change. Далее в теле функции оператор описания int temp используется с целью резервирования памяти. Мы хотим поме­стить значение переменной х в переменную temp, поэтому пишем temp = * u; Мы не должны писать, например, так:

temp = u; // неправильно

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



Поделиться:


Последнее изменение этой страницы: 2021-04-20; просмотров: 120; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.145.152.146 (0.011 с.)