Форум программистов, компьютерный форум CyberForum.ru

Функция с переменным количеством параметров-оъектов - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 25, средняя оценка - 4.72
SandWraith
 Аватар для SandWraith
187 / 187 / 13
Регистрация: 11.04.2009
Сообщений: 497
Завершенные тесты: 2
22.03.2011, 18:02     Функция с переменным количеством параметров-оъектов #1
Нашел на форуме пример функции с переменным количеством int, подскажите как переписать ее для передачи числа параметров-объектов произвольного класса MyClass?

Код
int sred_znach(int x,...);
{
int i=0, j=0, sum=0;
va_list uk_arg;
va_start(uk_arg,x); /* установка указателя uk_arg на */
/* первый необязятельный параметр */
if (x!=-1) sum=x; /* проверка на пустоту списка */
else return (0);
j++;
while ( (i=va_arg(uk_arg,int))!=-1)
/* выборка очередного */
{ /* параметра и проверка */
sum+=i; /* на конец списка */
j++;
}
В частности, как поменяется условие "( (i=va_arg(uk_arg,int))!=-1)"?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4237 / 2770 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
22.03.2011, 19:56     Функция с переменным количеством параметров-оъектов #2
Должно помочь
Постоянная работа с функциями типа printf или scanf вызывает у программистов зависть – это же функции с переменным количеством аргументов. А как написать свою функцию, обрабатывающую столько параметров, сколько будет задано в обращении, и, естественно, допускающую задание разного количество аргументов?

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

Если мы собираемся сообщать функции количество передаваемых ей аргументов, то заголовок функции можно оформить следующим образом:
double mid_var(int n,...)

Три точки в конце списка предупреждают компилятор о том, что он не должен контролировать количество и типы следующих аргументов. Все заботы о доступе к списку параметров переменной длины берет на себя вызываемая функция. Предположим, далее, что все аргументы передаются в функцию mid_var как значения, т.е. к моменту передачи управления функции они находятся в стеке. Добраться до них можно следующим образом. Заведем указатель типа int и занесем в него адрес формального параметра n (система знает, где находится стек, и адрес n ей доступен):
int *ip=&n;

Продвинем указатель ip на 1, т.е. переместимся на адрес начала следующего параметра, и занесем его в новый указатель dp уже типа double:
ip++; //переход на адрес первого слагаемого
double *dp=(double *)ip; //преобразование типа указателя

Теперь адрес начала списка слагаемых у нас есть, количество слагаемых мы тоже знаем, поэтому все остальное – дело техники. Окончательный вид функции таков:
double mid_var(int n,...)
{ int *ip=&n+1;
double *dp=(double *)ip;
double s=0.;
for(int j=0; j<n; j++)
s += dp[j]; //или s += *(dp+j); или s += *(dp++);
return s/n;
}

Теперь попытаемся построить аналогичную функцию, которая суммирует свои аргументы до тех пор, пока не встречает нулевое слагаемое. Она устроена еще проще:
double mid_var(double a1,...)
{ double *dp=&a1;
double s=0;
int c=0;
while(*dp != 0)
{ s += *(dp++); c++; }
return s/c;
}

Аналогичные функции можно построить, когда список передаваемых параметров состоит из переменного количества однотипных указателей. Только здесь придется использовать не просто указатели типа *dp, а "двойные" указатели типа **dp. И доставать значения нужных данных придется также через двойные указатели s += (**dp);

В файле stdarg.h находится несколько функций (точнее, макроопределений) которые обеспечивают перемещение по списку параметров, завершающемуся нулем:
va_list p; //объявление указателя на список параметров
va_start(p,p1); //установка указателя списка на последний явный
//параметр
va_arg(p,тип); //перемещение указателя на очередной неявный параметр
va_end(p); //уничтожение указателя на список параметров

Продемонстрируем использование этих средств на примере той же самой функции mid_var:
double mid_var(int n,...) //функции передают количество параметров
{ va_list p;
double s=0,c=0;
va_start(p,n);
while(n--) //до тех пор, пока n != 0
{ s += va_arg(p,double); c++; }
va_end(p);
return s/c;
}

Если список параметров начинается с первого слагаемого a1, то программа меняется очень незначительно:
double mid_var(double a1,...)
{ va_list p;
double s=0,c=0,u=a1;
va_start(p,a1);
do {s += u; c++; }
while(u=va_arg(p,double)); //до тех пор, пока u != 0
va_end(p);
return s/c;
}

На наш взгляд, применение обычных указателей выглядит несколько проще, чем использование стандартных средств.
SandWraith
 Аватар для SandWraith
187 / 187 / 13
Регистрация: 11.04.2009
Сообщений: 497
Завершенные тесты: 2
22.03.2011, 20:01  [ТС]     Функция с переменным количеством параметров-оъектов #3
если ей сообщают (например, значением первого аргумента) это число n, либо список параметров завершается обусловленным признаком – например, нулевым значением последнего параметра.
То есть... никак? Конечно, printf и scanf как-то работают, но... получается реализовать малой кровью нельзя?
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4237 / 2770 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
22.03.2011, 20:10     Функция с переменным количеством параметров-оъектов #4
То есть... никак?
Что никак? Там же все написанно, можно и под объекты написать, без разницы...
SandWraith
 Аватар для SandWraith
187 / 187 / 13
Регистрация: 11.04.2009
Сообщений: 497
Завершенные тесты: 2
22.03.2011, 20:14  [ТС]     Функция с переменным количеством параметров-оъектов #5
Никак написать нормальный вариант, такой же как prinf, без передачи количества аргументов или завершающего null.
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4237 / 2770 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
22.03.2011, 20:21     Функция с переменным количеством параметров-оъектов #6
такой же как prinf, без передачи количества аргументов или завершающего null.
Можно, в printf() (и прочих похожих ф-циях) используется "финт ушами" в виде специальной управляющей строки, которая состоит из служебных комбинаций символов – спецификаторов. Спецификаторы описывают тип и количество аргументов. Каждому из спецификаторов должна соответствовать "своя" переменная.
Если интересно, вот статья Криса Касперски на эту тему.
slice
32 / 75 / 4
Регистрация: 04.11.2010
Сообщений: 249
22.03.2011, 20:28     Функция с переменным количеством параметров-оъектов #7
Цитата Сообщение от SandWraith Посмотреть сообщение
Никак написать нормальный вариант, такой же как prinf, без передачи количества аргументов или завершающего null.
никак
Советую тебе не использовать функции с переменным числом параметров. К примеру несколько объектов можно запихать в контейнер и передать одним аргументом.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.03.2011, 20:29     Функция с переменным количеством параметров-оъектов
Еще ссылки по теме:

C++ Шаблон с переменным количеством параметров
Массив в функции с переменным количеством параметров C++
Функции с переменным количеством параметров в языке C ++ C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
SandWraith
 Аватар для SandWraith
187 / 187 / 13
Регистрация: 11.04.2009
Сообщений: 497
Завершенные тесты: 2
22.03.2011, 20:29  [ТС]     Функция с переменным количеством параметров-оъектов #8
В настоящей статье на примере функции printf рассматриваются ситуации, в которых отсутствие в языке Си встроенных средств определения количества переданных функции аргументов приводит к несанкционированному вторжению в защищенные системы, и предлагаются некоторые пути выхода из таких ситуаций.
Управляющая строка получается и есть неявная передача количества аргументов. Получается, в c++ как таковом ситуация не изменилась по сравнению с С (судя по описанию статьи).
Yandex
Объявления
22.03.2011, 20:29     Функция с переменным количеством параметров-оъектов
Ответ Создать тему
Опции темы

Текущее время: 16:17. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru