#cpp
Как передать переменное количество параметров х и у одной функции. Из этой задачи:
Написать функцию (или макроопределение), которая определяет принадлежит ли точка
с координатами (х , у) окружности с заданным радиусом R. Написать функцию
belong с переменным числом параметров, которая определяет сколько точек с координатами
(х , у) принадлежат заданной окружности. Написать вызывающую функцию main, которая
обращается к функции belong не менее трех раз с количеством параметров 3, 9, 11.
Cамо решение задачи не нужно.
Ответы
Ответ 1
Проблема в том, как группировать x и y. Мы можем засунуть их в структуру, например struct Point { float x, y; }; тогда задача сводится к "как написать функцию принимающую переменное количество параметров". Это просто, для этого есть шаблоны: #include#include struct Point { float x, y; }; template int f(const T&... args) { auto n = 0; auto R = 10; for (auto&& p : std::initializer_list {args...}) if (p.x*p.x + p.y*p.y - R*R < 0.0001) ++n; return n; } int main() { f(Point{11, 12}, Point{22, 23}); } Если же мы хотим передавать координаты последовательно, т.е. f(x1, y1, x2, y2), то мы опять можем использовать шаблоны, но уже с рекурсией: int f() { return 0; } template int f(float x, float y, const T&... tail) { return int(x*x + y*y - R*R < 0.0001) + f(tail...); } Ответ 2
Если это задание из ВУЗа, то вполне вероятно, что ожидается что-нибудь подобное: #include#include int max(size_t number, ...) { va_list argList; va_start(argList, number); int max = va_arg(argList, int); for(size_t i = 1; i < number; ++i) { int val = va_arg(argList, int); max = std::max(val, max); } va_end(argList); return max; } int main() { int maxVal = max(6, 12, 43215, 61, 516, 412222, 65125); std::cout << "Max value is: " << maxVal << std::endl; return 0; } В примере используется функция с переменным количеством параметров, где количество параметров задаётся первым. Решение предложенное @Abyx гораздо лучше, но есть и такое, которое унаследовано от C. Ответ 3
Variadic templates здесь использовать не нужно. Шаблонная магия - это что-то вроде кунг-фу. Настоящие мастера не используют её без необходимости. Кроме того, в данной ситуации это было бы просто неправильно методологически. Количество параметров слишком велико, а тип у них один и тот же. Variadic templates существуют в языке определённо не для таких случаев. Для таких случаев существуют контейнеры и итераторы. Приятным бонусом при использовании контейнера будет то, что функция для подсчёта элементов, удовлетворяющих некоторому условию, уже есть в стандартной библиотеке. Всё, что нужно сделать, это написать для неё обёртку, содержащую конкретное условие. #include#include using namespace std; struct Point { float x, y; Point(float x_, float y_) : x(x_), y(y_) { } }; template size_t belong(It first, It last, double r) { return count_if(first, last, [r](const typename It::reference itm) { return pow(itm.x, 2)+pow(itm.y, 2)-pow(r, 2) < 0.0001; }); } int main() { vector points; points.emplace_back(1.0, 1.0); points.emplace_back(2.0, 2.0); points.emplace_back(3.0, 3.0); size_t count = belong(begin(points), end(points), 10); // далее аналогично для 9 и 11 точек return 0; } Ответ 4
На мой взгляд, все три ответа имеют "право на жизнь", учитывая неконкретность вопроса и отсутствие постановки источника данных. В контексте запрошенного языка, я, как и уважаемый Shamov, прежде всего подумал о STL. Потому как, в реальной жизни, пакет точек получался бы алгоритмически (ну например, из stdin), а не во время компиляции, что автоматически отметает первый и последний ответ. Соответственно, контейнер подходит лучше. Если вдруг embedded case, реализовать через передачу массива структур. Если же, как ни странно, точки известны во время компиляции, можно шаблонами. Не забыть заплатить размером приложения. Если реально вузовское задание, возможно преподаватель хочет увидеть va_list :)
Комментариев нет:
Отправить комментарий