Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ответы по инфе.docx
Скачиваний:
1
Добавлен:
01.07.2025
Размер:
469 Кб
Скачать
☆

40. Локальные и глобальные величины программы

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

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

  • Они используют память в течение всего времени работы программы, а не тогда, когда они необходимы.

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

  • Использование большого числа глобальных переменных может вызвать ошибки в программе из-за неизвестных и нежелательных эффектов.

41. Способы обмена информацией между вызывающей и вызываемой функциями

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

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

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

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

int* f() { int a = 5; return &a; } // нельзя!

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

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

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

42. Передача функций в качестве параметров функций

Callback (англ. call — вызов, англ. back — обратный) или функция обратного вызова в программировании — передача исполняемого кода в качестве одного из параметров другого кода. Обратный вызов позволяет в функции исполнять код, который задаётся в аргументах при её вызове. Этот код может быть определён в других контекстах программного кода и быть недоступным для прямого вызова из этой функции. Некоторые алгоритмические задачи в качестве своих входных данных имеют не только числа или объекты, но и действия (алгоритмы), которые естественным образом задаются как обратные вызовы.

Техника программирования обратного вызова в языках программирования, подобных языку Си, проста. При вызове основной функции ей просто передаётся указатель на функцию обратного вызова. Классическим примером является функция qsort из библиотеки stdlib. Эта функция позволяет отсортировать массив блоков байт одинаковой длины. В качестве аргументов она получает адрес первого элемента массива, количество блоков в массиве, размер блока байт, и указатель на функцию сравнения двух блоков байт. Эта функция сравнения и есть функция обратного вызова.

typedef int (*CallbackType)(float);

void DoWork(CallbackType callback)

{

float variable = 0.0f;

int result = callback(variable);

}

int SomeCallback(float variable)

{

return variable * 2;

}

int main(int argc, char ** argv)

{

DoWork(&SomeCallback);

}

43. Перегрузка функций в языке C++

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

Например, функция print, принимающая строковый аргумент (или char *), выполняет задачи, совершенно отличающиеся от задач, выполняемых функцией, принимающей аргумент типа double. Перегрузка позволяет использовать универсальные имена и препятствует применению программистами таких имен, как print_str или print_d. В следующей таблице указаны компоненты объявления функций, используемые языком C++ для различения групп функций с одинаковым именем в одной области.