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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 25, средняя оценка - 4.72
SandWraith
188 / 188 / 13
Регистрация: 11.04.2009
Сообщений: 497
Завершенные тесты: 2
#1

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

22.03.2011, 18:02. Просмотров 3359. Ответов 7
Метки нет (Все метки)

Нашел на форуме пример функции с переменным количеством 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)"?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
22.03.2011, 18:02
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Функция с переменным количеством параметров-оъектов (C++):

Функция с переменным количеством параметров - C++
Доброго времени суток! Я озадачился таким вопросом - как производится компиляция функций с переменным числом параметров? Компилятор создаёт...

Функция с переменным количеством параметров - C++
Здравствуйте, возникла вот такая проблема: создаю функцию с переменным кол-ом параметров. Пример сделан мною по аналогии с...

Функция суммы с переменным количеством параметров - C++
На просторах форума нашёл код. Стало интересно посмотреть что выводят его отдельные части(отдельно переменная t, sum одного из аргументов и...

Функции по переменным количеством параметров - C++
нужна помощь по работе с такой функцией .. Искал в книге Страуструпа, не понял пример, помогите, как правильно описать и реализовать такую...

Шаблон с переменным количеством параметров - C++
У меня компилятор Visual Studio 2012, но не работает следующий код: #include <iostream> #include <string> void show_list() {} ...

Функции с переменным количеством параметров в языке C ++ - C++
Реализовать функцию конкатенации (сцепления) произвольного количества C-строк с динамическим изменением длины результирующей строки.

7
Kastaneda
Форумчанин
Эксперт С++
4655 / 2863 / 228
Регистрация: 12.12.2009
Сообщений: 7,275
Записей в блоге: 2
Завершенные тесты: 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;
}

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

Массив в функции с переменным количеством параметров - C++
Добрый день. Не могу разобраться, как в функции с переменным количеством параметров сделать указатель на элемент массива. Ниже код, на...

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

Функция с переменным числом параметров, как узнать кличество переданных параметров? - C++
Добрый вечер, можно не использовать int n, а каким то другим способом узнать количество переданных аргументов в функцию и адрес? int suma...

Функции с переменным количеством параметров, stdarg.h. Исправить код - C++
Почему не работает? В итоге получается 0, а если в функции все что надо заменить с float на int, то работает правильно. В чем ошибка? ...


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

Или воспользуйтесь поиском по форуму:
8
Yandex
Объявления
22.03.2011, 20:29
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru