Шаг 57.
Функции с переменным числом параметров

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

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

  <тип функции> <имя функции> (<спецификация явных параметров>,...); .

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

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

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

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

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


    Пример 1. Составить программу вычисления суммы заданных целых чисел с использованием количества слагаемых.
#include <iostream.h>
 void main()
 {
	long summa (int,...); //Прототип функции.
	cout << "\n summa(2,4,6)=" << summa (2,4,6);
	cout << "\n summa(6,1,2,3,4,5,6)="
		<< summa (6,1,2,3,4,5,6);
 }
 long summa (int k,...) //Передаем количество параметров.
 {
	int *pk=&k; //pk содержит адрес расположения начала списка параметров.
	long sm=0;
	for (;k;k--)
		  sm+=*(++pk);
	return sm;
 }
Текст этой программы можно взять здесь.

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


    Пример 2. Перепишем программу, используя предопределенное значение (пусть это будет 0).
#include<iostream.h>
 long summa (int k,...)
 {
	int *pk=&k;
	long sm=0;
	for (;*pk;) 
		  sm+=*(pk++);
	return sm;
 }
  void main() //Прототип функции sum отсутствует.
 {
	cout << "\n summa(4,6,0)="<< summa (4,6,0);
	cout << "\n summa(1,2,3,4,5,6,0)="
		<< summa (1,2,3,4,5,6,0);
	cout << "\n summa(1,2,0,4,5,6,0)="
		<< summa (1,2,0,4,5,6,0);
 }
Текст этой программы можно взять здесь.

    В последнем случае на экран будет выведено число 3, так как суммируются только числа 1 и 2.


    Проведите сравнительный анализ функций summa() в примерах 1 и 2. Объясните различия в реализации этих функций.


    На следующем шаге мы поговорим о подставляемых функциях.


Предыдущий шаг Содержание Следующий шаг