Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Техн.прогр.в.2.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
962.56 Кб
Скачать

Неявно заданные параметры функции

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

Функции и типы данных для работы с неявно заданными параметрами определены в библиотеке stdarg.h.

Рекурсия

Языки «С» и «С++» разрешают использование рекурсии, то есть вызова функцией самой себя.

Пример (функция вычисления факториала):

long fact(int k)

{

if (k<0) return 0;

if (k==0) return 1;

return k*fact(k-1);

}

Механизм вызова функций, подставляемые функции

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

– сохранения контекста выполнения функции, из которой происходит вызов: заключается, прежде всего, в сохранении некоторых регистров процессора;

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

– вызов функции по её адресу.

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

Таким образом, вызов функции является достаточно ресурсозатаратным процессом. Это в особенности справедливо, если тело функции не велико, а количество вызовов достаточно большое (например, вызов происходит в цикле). Казалось бы, в этом случае эффективнее не выделять в программе отдельные функции, но такое решение может не соответствовать принципам структурного программирования. Для такой ситуации введены подставляемые (inline) функции. Их тело компилируется непосредственно в точку их вызова, а не в отдельную область памяти. На такие функции накладывается ряд достаточно очевидных ограничений: в них недопустима рекурсия, нельзя объявить указатель на такую функцию. Большинство современных компиляторов автоматически выбирает режим (стандартный / подстановка) для функций.

Перегрузка функций. Параметры по умолчанию

Язык «С++» предоставляет дополнительные возможности:

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

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

1.7. Указатели. Массивы. Строки Обзор

Переменные хранят данные и не позволяют управлять их размещением в памяти, можно лишь определить адрес их размещения (операция «&»).

Указатель на переменную хранит адрес размещения данного. Обратиться к данному можно через операцию разыменовывания указателя (*). Объявление указателя осуществляется символом «*» перед именем переменной. Пример:

int x;

int *t; // объявили указатель t на переменную типа int

t = &x; // присваиваем указателю адрес переменной x

*t = 4; // используя указатель, присваиваем x значение 4

Указатели и объекты одного типа могут быть объявлены вместе. Пример (другая реализация предыдущего примера):

int x,*t=&x;

Константа NULL предназначена для обозначения неинициализированных указателей.

Для обращения к полям структур, передаваемых по указателю, используется символ «->».

Пример:

struct S {int a; float b;};

int Func(S*s)

{

(*s).a = 3; // можно обратиться к полю так

s->b = 5.6 // а можно и так

return 0;

}