Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 19.04.2017, 00:27   #1
Mas0n_
Пользователь
 
Регистрация: 22.10.2016
Сообщений: 22
По умолчанию Функции с переменным числом параметров С++

Решил ещё в этой теме написать.
У меня есть две функции:
Код:
int mul(short n, ...)
{
	int *p = (int*)&n;
	int res = 1;
	for (int i = 1; i <= n; i++)
		res *= *(++p);
	return res;
}

double sum(float n, ...)
{
	double *p = (double*)&n;
	double res = 0;
	while ((float)*p != FLT_MAX)
		res += *(p++);
	return res;
}
Первая функция работает нормально, параметры передаются, результат произведения элементов возвращает.
Вторая функция должна возвращать сумму элементов с первого по предпоследний, в качестве последнего параметра передается FLT_MAX, но суть не в этом. Почему-то в этой функции из-за явного преобразования типа (или из-за чего-то другого), он принимает совершенно другие значения.
Например:
Код:
double r = sum(1.12, 3.42, 4.3, FLT_MAX);
В отладчике видно, что переменная p вначале равна 0x0097fbf0 {-1.7835458874333207e+259}. Чтот это не очень похоже на 1.12. Или я чего-то не понимаю? Да и не возвращает она ничего, ошибку выкидывает.

Объясните пожалуйста, почему так. И как исправить функцию? (то, что тип возвращаемого результата не совпадает с типом принимаемых параметров это нормально, так по заданию нужно)
Mas0n_ вне форума Ответить с цитированием
Старый 19.04.2017, 05:54   #2
Croessmah
Вредный кошак
Участник клуба
 
Аватар для Croessmah
 
Регистрация: 14.10.2012
Сообщений: 1,159
По умолчанию

Цитата:
Или я чего-то не понимаю?
С ellipsis работают с помощью va_* макросов.
Croessmah вне форума Ответить с цитированием
Старый 19.04.2017, 06:48   #3
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,329
По умолчанию

А почему берете указатель double?
Попробуйте заменить на float.
waleri вне форума Ответить с цитированием
Старый 19.04.2017, 10:20   #4
Mas0n_
Пользователь
 
Регистрация: 22.10.2016
Сообщений: 22
По умолчанию

Цитата:
Сообщение от Croessmah Посмотреть сообщение
С ellipsis работают с помощью va_* макросов.
Почему тогда предыдущая функция работает?
Или вот например
Код:
double sum(double n, ...)
{
	double *p = &n;
	double res = 0;
	while (*p != DBL_MAX)
		res += *(p++);
	return res;
}
Тоже работает.
Mas0n_ вне форума Ответить с цитированием
Старый 19.04.2017, 10:24   #5
Mas0n_
Пользователь
 
Регистрация: 22.10.2016
Сообщений: 22
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
А почему берете указатель double?
Попробуйте заменить на float.
Вот так? так тоже пробовал. Не работает. А по заданию (я студент) обязательно нужно принимать float, а возвращать double. Не знаю, как ещё можно это сделать.
Код:
double sum(float n, ...)
{
	float *p = &n;
	double res = 0;
	while (*p != FLT_MAX) {
		res += (double)*(p++);
	}
	return res;
}
Mas0n_ вне форума Ответить с цитированием
Старый 19.04.2017, 10:27   #6
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
Сообщение от Mas0n_ Посмотреть сообщение
Не знаю, как ещё можно это сделать.
А если так?

Код:
double fvarparm(float n, ...)
{
	float *p = &n;
	double res = 0;
	while (*p != FLT_MAX) {
		res += (float)*(p++);
	}
	return res;
}
Serge_Bliznykov вне форума Ответить с цитированием
Старый 19.04.2017, 10:36   #7
Croessmah
Вредный кошак
Участник клуба
 
Аватар для Croessmah
 
Регистрация: 14.10.2012
Сообщений: 1,159
По умолчанию

Цитата:
Сообщение от Mas0n_ Посмотреть сообщение
Почему тогда предыдущая функция работает?
Невезучий Вы, только поэтому.

Код:
#include <iostream>
#include <cstdarg>

double sum(int n, ...)
{
    double result = 0.0;
    va_list vl;
    va_start(vl, n);
    for (int i = 0; i < n; i++)
    {
        double val = va_arg(vl, double);
        result += val;
    
    }
    va_end(vl);
    return result;
}




int main()
{
    std::cout << sum(3, 5.4f, 3.3f, 1.2f);
}
http://rextester.com/IGYWV89197

Последний раз редактировалось Croessmah; 19.04.2017 в 10:44.
Croessmah вне форума Ответить с цитированием
Старый 19.04.2017, 10:37   #8
Croessmah
Вредный кошак
Участник клуба
 
Аватар для Croessmah
 
Регистрация: 14.10.2012
Сообщений: 1,159
По умолчанию

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
А если так?
При передаче float в ellipsis он продвигается в double.
Croessmah вне форума Ответить с цитированием
Старый 19.04.2017, 17:11   #9
Mas0n_
Пользователь
 
Регистрация: 22.10.2016
Сообщений: 22
По умолчанию

Цитата:
Сообщение от Croessmah Посмотреть сообщение

Код:
#include <iostream>
#include <cstdarg>

double sum(int n, ...)
{
    double result = 0.0;
    va_list vl;
    va_start(vl, n);
    for (int i = 0; i < n; i++)
    {
        double val = va_arg(vl, double);
        result += val;
    
    }
    va_end(vl);
    return result;
}

int main()
{
    std::cout << sum(3, 5.4f, 3.3f, 1.2f);
}
Почему нельзя обойтись без этих макросов?
Mas0n_ вне форума Ответить с цитированием
Старый 19.04.2017, 17:33   #10
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,706
По умолчанию

Можно, но весь их функционал прийдется реализовать самому. Включая выравния и варианты с размерами.
p51x вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Функции с переменным числом параметров (С) Polly0819 Помощь студентам 2 18.12.2012 17:10
функция с переменным числом параметров Veselyn Общие вопросы C/C++ 1 08.04.2010 16:36
Функции с переменным числом параметров Matr1x Общие вопросы C/C++ 2 07.01.2010 16:55