При макровызове за идентификатором следует спи сок фактических аргументов, количество которых сле дует сделать совпадающим с количеством формальны параметров.
Пример:
#define MAX(x,y) ((x) > (y))?(x): (y)
Приведенная директива заменит фрагмент t = = MAX(i,s[i]) на выражение t = ((i) > (s[i])?(i): (s[i]).
Как и в ранее приведенном примере, круглые скобки, в которые заключены формальные параметры макроопределения, дают возможность избежать ошибок, связанных с неправильным порядком осуществления, если фактические аргументы являются выражениями.
Например, если есть скобки, фрагмент
t = MAX(i&j, s[i]||j) будет заменен выражением
t = ((i&j) > (s[i]||j)?(i&j): (s[i]||j); а если скобок нет – фрагментом
t = (i&j>s[i]||j)?i&j: s[i]||j;
где условное выражение вычисляется в другом порядке.
Директива #undef применяется для отмены действия директивы #define. Синтаксис данной директивы следующий: #undef идентификатор.
Директива отменяет операцию текущего определения #define для определенного идентификатора.
Функция является рекурсивной, когда во время обработки появляется ее повторный вызов непосредственно или косвенно, через цепочку вызовов других функций.
Прямая (непосредственная) рекурсия – это вызов функции внутри тела этой функции.
int a()
{…..a()…..}
Косвенная рекурсия – это рекурсия, которая осуществляет рекурсивный вызов функции через цепочку вызова других функций. Все функции, которые входят в цепочку, тоже являются рекурсивными. Рассмотрим пример:
a(){…..b()…..}
b(){…..c()…..}
c(){…..a()…..}.
Все представленные функции a, b, c считаются рекурсивными, так как в случае вызова одной из них производится вызов других и самой себя.
Последовательность вызовов процедуры tn, если m = 3, можно проиллюстрировать древовидной структурой (рис. 2). Всякий раз при вызове процедуры tn под параметры n, i, j, w определяется память и запоминается место возврата. В случае возврата из процедуры tn память, которая выделяется под параметры n, i, j, w, освобождается и становится доступной память, которая выделена под параметры n, i, j, w предыдущим вызовом, а управление передается в место возврата.
Рис. Последовательность вызовов процедуры tn
Очень часто рекурсивные функции можно заменить нерекурсивными функциями или фрагментами. Это производится путем использования стеков для хранения точек вызова и вспомогательных переменных.
20. Знакомство с языком СИ++
Рассмотрим ряд программ и частей программ на C++.
Прежде всего, рассмотрим программу, которая выводит строку выдачи:
#include
main()
{
cout << «Hello, world\n»; }