Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.89/27: Рейтинг темы: голосов - 27, средняя оценка - 4.89
 Аватар для SandWraith
189 / 189 / 38
Регистрация: 11.04.2009
Сообщений: 497

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

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

Студворк — интернет-сервис помощи студентам
Нашел на форуме пример функции с переменным количеством int, подскажите как переписать ее для передачи числа параметров-объектов произвольного класса MyClass?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
22.03.2011, 18:02
Ответы с готовыми решениями:

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

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

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

7
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
22.03.2011, 19:56
Должно помочь
Постоянная работа с функциями типа 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
189 / 189 / 38
Регистрация: 11.04.2009
Сообщений: 497
22.03.2011, 20:01  [ТС]
если ей сообщают (например, значением первого аргумента) это число n, либо список параметров завершается обусловленным признаком – например, нулевым значением последнего параметра.
То есть... никак? Конечно, printf и scanf как-то работают, но... получается реализовать малой кровью нельзя?
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
22.03.2011, 20:10
То есть... никак?
Что никак? Там же все написанно, можно и под объекты написать, без разницы...
0
 Аватар для SandWraith
189 / 189 / 38
Регистрация: 11.04.2009
Сообщений: 497
22.03.2011, 20:14  [ТС]
Никак написать нормальный вариант, такой же как prinf, без передачи количества аргументов или завершающего null.
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
22.03.2011, 20:21
такой же как prinf, без передачи количества аргументов или завершающего null.
Можно, в printf() (и прочих похожих ф-циях) используется "финт ушами" в виде специальной управляющей строки, которая состоит из служебных комбинаций символов – спецификаторов. Спецификаторы описывают тип и количество аргументов. Каждому из спецификаторов должна соответствовать "своя" переменная.
Если интересно, вот статья Криса Касперски на эту тему.
0
79 / 78 / 6
Регистрация: 04.11.2010
Сообщений: 249
22.03.2011, 20:28
Цитата Сообщение от SandWraith Посмотреть сообщение
Никак написать нормальный вариант, такой же как prinf, без передачи количества аргументов или завершающего null.
никак
Советую тебе не использовать функции с переменным числом параметров. К примеру несколько объектов можно запихать в контейнер и передать одним аргументом.
0
 Аватар для SandWraith
189 / 189 / 38
Регистрация: 11.04.2009
Сообщений: 497
22.03.2011, 20:29  [ТС]
В настоящей статье на примере функции printf рассматриваются ситуации, в которых отсутствие в языке Си встроенных средств определения количества переданных функции аргументов приводит к несанкционированному вторжению в защищенные системы, и предлагаются некоторые пути выхода из таких ситуаций.
Управляющая строка получается и есть неявная передача количества аргументов. Получается, в c++ как таковом ситуация не изменилась по сравнению с С (судя по описанию статьи).
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
22.03.2011, 20:29
Помогаю со студенческими работами здесь

Функция bit с переменным количеством параметров
Можете помочь, если не сложно: &quot;Напишите функцию bit с переменным количеством параметров, которая...

Функция mult с переменным количеством параметров
Подскажите почему не работает код, вот условие: Напишите функцию mult с переменным количеством...

Функция с переменным количеством параметров находящая произведение чисел типа flоat
2. Напишите функцию tult с переменным количеством параметров, которая находит произведение чисел...

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

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


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2). Унарный минус обозначается как ! */ #include <iostream> #include <stack> #include <cctype>. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru