Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
мини конспект по С++.doc
Скачиваний:
28
Добавлен:
25.03.2015
Размер:
782.85 Кб
Скачать

Классы памяти.

В языке С/C++ каждая переменная принадлежит к одному из четырех классов памяти:

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

  • auto- автоматический;

  • register- регистровый.

  1. статическая память, которая распределяется на этапе трансляции и заполняется по умолчанию нулями, атрибуты статической памяти:

  • внешний – extern;

  • статический – static.

Тип памяти указывается ключевым словом (auto, extern, static, register), стоящим перед спецификацией типа переменной. Например,

register int a;

По умолчанию переменная относится к классу auto и будет размещена в стеке.

Рекурсивные функции.

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

Пример рекурсивной функции – вычисление факториала числа n!=1*2*3*…*n:

int fac(int n)

{

int b;

if (n==1) return 1;

b=fac(n-1)*n;

return n;

}

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

Операция typedef

Любому типу данных, как стандартному, так и определенному пользователем, можно задать новое имя с помощью операции

typedef <тип> <новое_имя>;

Введенный таким образом новый тип используется аналогично стандартным типам, например, введя пользовательские типы:

typedef int INT;

typedef char Mass_str[100];

декларации идентификаторов введенных типов имеют вид:

INT i, j; → две переменные iиjтипаint;

Mass_strstr[10]; → массивstrиз 10 строк по 100 символов.

Указатели на функции

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

Рассмотрим методику работы с указателями на функции:

1. Как и любой объект языка Си, указатель на функции необходимо декларировать. Формат объявления указателя на функции следующий:

тип (*переменная-указатель) (список параметров);

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

float (*p_f) (char, float);

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

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

переменная-указатель = имя_функции;

Например, имеется функция с прототипом

float f1(char, float);

тогда операция

p_f = f1;

установит указатель p_f на данную функцию.

3. Вызов функции после установки на нее указателя выглядит так:

(*переменная-указатель)(список аргументов);

или

переменная-указатель (список аргументов);

После таких действий кроме стандартного обращения к функции

имя_функции(список аргументов);

появляется еще два способа вызова функции:

(*переменная-указатель)(список аргументов);

или

переменная-указатель (список аргументов);

Последнее справедливо, так как p_f также является адресом начала функции в оперативной памяти. Для нашего примера к функции f1 можно обратиться следующими способами:

f1(‘z’, 1.5); // Обращение к функции по имени

(* p_f)(‘z’, 1.5); // Обращение к функции по указателю

p_f(‘z’, 1.5); // Обращение к функции по имени указателя

4. Пусть имеется вторая функция с прототипом:

float f2(char, float);

тогда, переустановив указатель p_f на эту функцию:

p_f = f2;

имеем опять три способа ее вызова:

f2(‘z’, 1.5); // по имени функции

(* p_f)(‘z’, 1.5); // по указателю на функцию

p_f(‘z’, 1.5); // по имени указателя на функцию

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