
- •Лабораторная работа 1
- •Лабораторная работа 2 Переменные и константы. Базовые типы. Арифметические операции
- •Операции
- •Ввод и вывод данных
- •Лабораторная работа 3 Циклический и ветвящийся поток управления
- •Алгоритмы разветвляющейся структуры
- •Операторы выбора
- •Операторы циклов
- •Операторы перехода
- •Задание
- •Лабораторная работа 4 Функции. Вызов функций с формальными параметрами, передаваемыми по значению
- •Задание
- •Лабораторная работа 5 Одномерные массивы
- •Задание
- •Лабораторная работа 6 Многомерные массивы
- •Задание
- •Лабораторная работа 7 Функции для работы с символами
- •Лабораторная работа 8 Строки, литералы. Передача строк в функции
- •Строки и литералы
- •Библиотечные функции для работы со строками
- •Выделение памяти под строки
- •Передача строк в качестве параметров функций
- •Задание
- •Лабораторная работа 9 Указатели и динамические массивы
- •Задание
- •Варианты
- •Лабораторная работа 10 Динамические структуры данных
- •Структуры и указатели
- •Задание
- •Лабораторная работа 11 Объектно-ориентированное программирование. Создание классов и объектов
- •Задание
- •Лабораторная работа 12 Знакомство со средой быстрой разработки приложений. Использование компонент библиотеки vcl
- •Лабораторная работа 13 Вывод в форму результатов работы программы
- •Лабораторная работа 14 Изучение обработчиков событий компонентов библиотеки vcl
- •Лабораторная работа 15 Использование таймера для создания различных эффектов
- •Лабораторная работа 16 Рисование в канве. Построение графиков функций
- •Лабораторная работа 17 Изучение принципа работы текстового редактора
- •Список рекомендуемой литературы
- •Оглавление
Лабораторная работа 4 Функции. Вызов функций с формальными параметрами, передаваемыми по значению
Цель работы – приобрести навыки работы с функциями в языке С++.
Теория
Функция
Функция – это подпрограмма, которая может оперировать данными и возвращать значение. Каждая программа на языке С++ содержит, по крайней мере одну функцию – main(), которая при запуске программы вызывается автоматически. Функция main() может вызывать другие функции, а те, в свою очередь, могут вызывать следующие и т.д.
Каждая функция состоит из заголовка и тела. Заголовок – это прототип, только в конце точка с запятой не ставится. В заголовке задается имя функции, список параметров, тип возвращаемого значения. Тело функции – это блок. Тело функции определяет алгоритм работы.
Рассмотрим программу, печатающую степени числа 2:
float pow(float, int); /*pow() определена в другом месте*/
main()
{
for (int i=0; i<10; i++)
cout << pow(2,i) << "\n";
}
Первая строка функции – описание, указывающее, что pow – функция, получающая параметры типа float и int и возвращающая float. Описание функции используется для того, чтобы сделать определенными обращения к функции в других местах.
При вызове функции тип каждого параметра функции сопоставляется с ожидаемым типом точно так же, как если бы инициализировалась переменная описанного типа. Это гарантирует надлежащую проверку и преобразование типов. Например, обращение pow(12.3,"abcd") вызовет недовольство компилятора, поскольку "abcd" является строкой, а не int. При вызове pow(2,i) компилятор преобразует 2 к типу float, как того требует функция. Функция pow может быть определена следующим образом.
Пример
float pow(float x, int n)
{
if(n<0)error("извините, отрицательный показатель для pow()");
switch (n)
{
case 0: return 1;
case 1: return x;
default: return x*pow(x,n-1);
}
}
Первая часть определения функции задает имя функции, тип возвращаемого ею значения (если таковое имеется) и типы и имена ее параметров (если они есть). Значение возвращается из функции с помощью оператора return.
Каждая функция в программе на С++ должна быть один раз определена и может быть объявлена несколько раз по мере необходимости. По правилам языка С++ функция должна быть определена (или объявлена) до того, как использована (вызвана).
Определение функции состоит из двух частей: заголовка и тела. В общем случае заголовок функции включает следующие части:
спецификаторы класса памяти: extern или static. По умолчанию – extern;
тип возврата, возможно void. По умолчанию – int;
модификаторы;
имя функции;
список объявления параметров;
спецификацию исключений throw (список типов исключений).
Спецификация класса памяти влияет на область видимости имени функции. Так спецификатор extern означает, что объявленная функция доступна из любого места программы.
Тело функции – это блок, т. е. последовательность описаний переменных и операторов, заключенных в фигурные скобки. Даже если функция не выполняет никаких действий, тело функции должно присутствовать в определении. В этом случае тело функции будет состоять просто из скобок { }.
Примеры определений функций
void print (char *name, int value) //Ничего не возвращает
{
cout << “\n” << name << value; //Нет оператора return
}
float min (float a, float b) //В функции два оператора возврата
{
if (a<b) return a; //Возвращает минимальное
return b; //из значений аргумента
}
float cube (float x) // возвращает значение типа float
{
return x*x*x; // Возведение в куб вещественного числа
}
void write (void) //Ничего не возвращает,
{ //ничего не получает
cout << “\n имя: ”; //Всегда печатает одно и то же
}
Определения функций не должны быть вложенными. В отличие от определений, прототипы – объявления функции – могут быть вложенными в другие функции. Главное, чтобы прототип был прописан до вызова соответствующей функции.
Пример
float Max(float x, float y) // определение до вызова
{
return (x<y ? y : x);
}
void main ()
{
float Cube (float a); // прототип вложен до определения в
//главную функцию
int cc=15, k=2;
k=Cube (k);
cc=5+Max(k, cc)/3+ Cube(k); // вызовы функций
cout << c;
}
float Cube (float x) //определение функции Cube
{
return (x*x*x);
}
Результат: 522
Параметры
Параметр – это значение некоторого данного, которое нужно передать из одной функции в другой. При передаче параметров они сохраняются в стеке. Вы можете менять параметры в функции, но, так как вы меняете параметр, сохраненный в стеке, то при возврате из функции все изменения будут потеряны. Если вы хотите получить из функции модифицированные параметры, то следует передавать в функцию не сами параметры, а их адреса, и в функции, соответственно работать с адресами.
Пример
#include <iostream.h>
void main()
{
int fun(int x);
int a=5;
fun(a);
cout << fun(a);
}
int fun(int x)
{
return (x++);
}
Результат: 6.
Несмотря на то, что в функции параметр меняется, в основной программе значение переменной a остается неименной. Вот как выглядит та же программа при работе с адресами:
Пример
#include <iostream.h>
void main()
{
int fun(int *x);
int a=5;
fun(&a);
cout << fun(a);
}
int fun(int *x)
{
return (*x++);
}
Результат: 6.
Локальные и внешние переменные
Разность между ними состоит в определении области действия. Внешние (external) переменные отличаются тем, что имеют глобальную область действия, доступны любой функции.
Пример:
int x=456;
main()
{
cout << x;
}
Хотя x определена за пределами функции main, она доступна в этой функции.
Локальные переменные доступны только в теле тех функций, в которых они определены. Если возникает конфликт между именами глобальных и локальных переменных, то выигрывают локальные.
Пример
int x=456; //глобальное описание
main()
{
int x=675; // локальное описание
cout << x;
}
Результат: 675.