Функции. Основные принципы структурной методологии. Принцип формальности. Принцип иерархического упорядочивания, страница 14

   }

//-------------------------------------------------------------void repchar(char ch, int n)     

{                             

for(int j=0; j<n; j++)        

cout << ch;                

cout << endl;

}

Результаты работы:

*********************************************

=============================================

++++++++++++++++++++++++++++++

Язык программирования С++ допускает использование в функциях переменного числа аргументов. Признаком функции с переменным числом аргументов является многоточие в списке параметров прототипа функции. Встретив (…), компилятор прекращает контроль соответствия типов параметров для такой функции.

Если список формальных параметров функции заканчивается многоточием, это означает, что при ее вызове на этом месте можно указать еще несколько параметров. Проверка соответствия типов для этих параметров не выполняется, char и short передаются как int, a float – как double. В качестве примера можно привести функцию printf, прототип которой имеет вид:

int printf (const char*, …);

Это означает, что вызов функции должен содержать, по крайней мере, один параметр типа char* и может либо содержать, либо не содержать другие параметры:

printf (”Input a,b,c”);                         //один параметр

printf (”summa= %5.2f ”, sum);        //два параметра

printf (”%d%d%d%d”, a,b,c,d);        //пять параметров 

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

Рассмотрим два варианта функции example(), которая принимает переменное число аргументов и выводит на печать их количество и принятые значения. В первом варианте функции число действительно переданных через стек значений задает первый аргумент:

#include <stdio.h>

void example (int,...);

void main(void)

{int var1=5, var2=6, var3=7, var4=8, var5=9;

example(2, var1);                             //вызов функции с двумя аргументами

example(3, var1, var2);                   //вызов функции с тремя аргументами

example(6, var1, var2, var3, var4, var5);        //а теперь – шесть аргументов

}

void example(int arg1, ...)

{int *ptr=&arg1;                        //установка указателя на первый аргумент

printf("\n peredano argumentov %d:\n", arg1);

for ( ; arg1; arg1--)

{printf("%d   ", *ptr); ptr++;}                         //2 5        3 5 6        6 5 6 7 8 9

printf ("\n");

}

 


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

#include <stdio.h>

void example (int,...);

void main(void)

{int var1=5, var2=6, var3=7, var4=8, var5=9;

example(var1, 0);                       //вызов функции с двумя аргументами

example(var1, var2, 0);               //вызов функции с тремя аргументами

example(var1, var2, var3, var4, var5, 0); //а теперь – шесть аргументов

}

void example(int arg1, ...)

{int number = 1;

int *ptr=&arg1;                          //установка указателя на первый аргумент

while(*ptr++)

number++;

printf("\n peredano argumentov %d:\n", number-1);

&arg1       

 

ptr       

 
}

Перегрузка функций

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