|
189 / 189 / 38
Регистрация: 11.04.2009
Сообщений: 497
|
||||||
Функция с переменным количеством параметров-оъектов22.03.2011, 18:02. Показов 5757. Ответов 7
Метки нет (Все метки)
Нашел на форуме пример функции с переменным количеством int, подскажите как переписать ее для передачи числа параметров-объектов произвольного класса MyClass?
0
|
||||||
| 22.03.2011, 18:02 | |
|
Ответы с готовыми решениями:
7
Функция с переменным количеством параметров
Функция суммы с переменным количеством параметров |
|
|
|
| 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
|
|
|
189 / 189 / 38
Регистрация: 11.04.2009
Сообщений: 497
|
||
| 22.03.2011, 20:01 [ТС] | ||
0
|
||
|
189 / 189 / 38
Регистрация: 11.04.2009
Сообщений: 497
|
|
| 22.03.2011, 20:14 [ТС] | |
|
Никак написать нормальный вариант, такой же как prinf, без передачи количества аргументов или завершающего null.
0
|
|
|
|
||
| 22.03.2011, 20:21 | ||
Если интересно, вот статья Криса Касперски на эту тему.
0
|
||
|
79 / 78 / 6
Регистрация: 04.11.2010
Сообщений: 249
|
||
| 22.03.2011, 20:28 | ||
|
Советую тебе не использовать функции с переменным числом параметров. К примеру несколько объектов можно запихать в контейнер и передать одним аргументом.
0
|
||
|
189 / 189 / 38
Регистрация: 11.04.2009
Сообщений: 497
|
||
| 22.03.2011, 20:29 [ТС] | ||
0
|
||
| 22.03.2011, 20:29 | |
|
Помогаю со студенческими работами здесь
8
Функция bit с переменным количеством параметров
Функция с переменным количеством параметров находящая произведение чисел типа flоat Функция с переменным количеством параметров Функция с переменным числом параметров, как узнать кличество переданных параметров? Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Символьное дифференцирование
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, то после закрытия окошка. . .
|