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

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

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль

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

Ответ
 
Опции темы Поиск в этой теме
Старый 09.02.2012, 15:25   #1
lotus1994
Пользователь
 
Регистрация: 05.02.2012
Сообщений: 11
По умолчанию Функция сложения с переменным числом параметров C++

Эта функция почему-то неправильно считает сумму. Выдает результат (-156413698). Не знаю как правильно ее написать. Подскажите
Код:
int sum(int count, ...)
{
    int s = 0;

    for(int i = 1; i <= count; i++)
        s += (&count)[i];   
     
    return s;
}

int main()
{
    cout << sum(10, 20, 30, 40) << endl;

    return 0;   
}
lotus1994 вне форума Ответить с цитированием
Старый 09.02.2012, 16:33   #2
rUs_LAN
Форумчанин
 
Регистрация: 15.11.2008
Сообщений: 577
По умолчанию

блин, а я даже подумать не мог что так можно. Действительно с + + сложный язык.

Тем не менее полазив по гуглу я понял что первый параметр должен быть количество аргументов. А ваша программа должна выглядеть примерно так


Код:

#include <iostream>
#include <stdio.h>
#include <stdarg.h>

int sum(int count, ...)
{
    int s = 0;

	 va_list ap;
	 va_start(ap, count);

    for(int i = 1; i <= count; i++)
        s += va_arg(ap, int);

	 va_end(ap);
     
    return s;
}


int main()
{
	 std::cout << sum(5, 20, 30, 40, 1, 1) << std::endl;
   
}
хотя это скорее С а не С + + ну если не считать iostream

Последний раз редактировалось rUs_LAN; 09.02.2012 в 16:37.
rUs_LAN вне форума Ответить с цитированием
Старый 09.02.2012, 16:43   #3
lotus1994
Пользователь
 
Регистрация: 05.02.2012
Сообщений: 11
По умолчанию

Спасибо большое за помощь rUs_LAN. А то я думал-думал. Теперь хоть все стало понятно.
lotus1994 вне форума Ответить с цитированием
Старый 09.02.2012, 16:48   #4
lotus1994
Пользователь
 
Регистрация: 05.02.2012
Сообщений: 11
По умолчанию

Вот так тоже можно. Это даже понятнее получается
Код:
int sum(int count, ...)
{
    int s = 0;

    for(int i = 1; i <= count; i++)
        s += (&count)[i];   
     
    return s;
}

int main()
{
    std::cout << sum(5, 20, 30, 40, 1, 1) << std::endl;

    return 0;   
}

Последний раз редактировалось lotus1994; 09.02.2012 в 16:52.
lotus1994 вне форума Ответить с цитированием
Старый 09.02.2012, 16:57   #5
rUs_LAN
Форумчанин
 
Регистрация: 15.11.2008
Сообщений: 577
По умолчанию

А мне вот по большому счету ничего не понятно.

Как правильно и где это надо использовать

жду комментариев Сыроежки
rUs_LAN вне форума Ответить с цитированием
Старый 09.02.2012, 19:41   #6
Сыроежка
Форумчанин
 
Регистрация: 01.07.2011
Сообщений: 423
По умолчанию

Правильно конечно использовать стандартные средства, то есть включить заголовок <cstdarg> и применять соответствующие макро va_start, va_arg, va_end и т.д.

Так как предложенное решение

Код:
int sum(int count, ...)
{
    int s = 0;

    for(int i = 1; i <= count; i++)
        s += (&count)[i];   
     
    return s;
}
в общем случае не будет работать, если тип первого параметра отличается от типа следующих за ним параметров. Например, если тип первого параметра (count ) int, а последующих, то есть заданных аргументов при вызове функции, short или char.
Также применение нестандартных средств затрудняет чтение кода, так как надо разбираться, а что пытается сделать программист.
Со мной можно встретиться на www.clipper.borda.ru
Сыроежка вне форума Ответить с цитированием
Старый 09.02.2012, 19:43   #7
rUs_LAN
Форумчанин
 
Регистрация: 15.11.2008
Сообщений: 577
По умолчанию

спасибо!!!
rUs_LAN вне форума Ответить с цитированием
Старый 09.02.2012, 20:35   #8
netrino
Участник клуба
 
Аватар для netrino
 
Регистрация: 15.07.2008
Сообщений: 1,933
По умолчанию

Цитата:
Сообщение от Сыроежка Посмотреть сообщение
в общем случае не будет работать, если тип первого параметра отличается от типа следующих за ним параметров. Например, если тип первого параметра (count ) int, а последующих, то есть заданных аргументов при вызове функции, short или char.
Вообще-то, как раз в этом случае работать будет, но по чистой случайности, так как int на 32-битных машинах соответствует машинному слову и выравниванию, с которым данные кладутся в стек. Если объявить count, например, как short, то уже работать ничего не должно. Более того, если скомпилировать под Win64, тоже работать не должно. И кстати, на линуксе (или там freebsd?) тоже не работает, не смотря на 32-х битность. Так что, использование stdarg.h не прихоть, а необходимость.

Последний раз редактировалось netrino; 09.02.2012 в 20:41.
netrino вне форума Ответить с цитированием
Старый 09.02.2012, 21:22   #9
rUs_LAN
Форумчанин
 
Регистрация: 15.11.2008
Сообщений: 577
По умолчанию

Код:

#include <iostream>
#include <cstdarg>


int sum(short count, ...)
{
    int s = 0;

	 va_list ap;
	 va_start(ap, count);

    for(int i = 1; i <= count; i++)
        s += va_arg(ap, int);

	 va_end(ap);

	
    return s;
}


int main()
{
	 std::cout << sum(6, 20, (unsigned short)30, (long long)40, 1, 10) << std::endl;   
	 std::system("pause");
}
xp 32bit работает

add: ну работает но не совсем работает, мой код скорее всего написан с ошибками, у меня в 1 аргумент (количество параметров) написано 6, хотя в действительности я так понимаю должно быть 5. Если написать 5 последний параметр не воспринимается, это происходит из-за того, что есть тип (long long) подозреваю что из-за того что он занимает 8 байт а не 4. Далее копаться не стал.

Последний раз редактировалось rUs_LAN; 09.02.2012 в 21:49.
rUs_LAN вне форума Ответить с цитированием
Старый 09.02.2012, 21:40   #10
Сыроежка
Форумчанин
 
Регистрация: 01.07.2011
Сообщений: 423
По умолчанию

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

#include <iostream>
#include <cstdarg>


int sum(short count, ...)
{
    int s = 0;

	 va_list ap;
	 va_start(ap, count);

    for(int i = 1; i <= count; i++)
        s += va_arg(ap, int);

	 va_end(ap);

	
    return s;
}


int main()
{
	 std::cout << sum(6, 20, (unsigned short)30, (long long)40, 1, 10) << std::endl;   
	 std::system("pause");
}
xp 32bit работает
Это скорей всего из-за того, что вы делаете приведение типов в стиле С, которые не влияют на внутреннее представление данных.
Попробуйте заменить вызов функции на следующий

sum(6, 20, 'a', 'b', 40ll, 1, 10ll )

Посмотрим, что будет.

Да, и считайте не сумму, а просто выведите их на печать. Так как в сумме есть особенность. Например, если есть тип long long, то он может быть разбит на два типа int, в котором одна часть будет равна 0, а вторая часть тому значению, которое вы передали. Поэтому при суммировании получится верное значение: сложатся две части одного числа, одна из которых (старшая часть) равна 0.
Со мной можно встретиться на www.clipper.borda.ru

Последний раз редактировалось Сыроежка; 09.02.2012 в 21:42.
Сыроежка вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Варнинги в функциях с переменным числом параметров guz Общие вопросы C/C++ 0 15.11.2010 13:36
функция с переменным числом параметров Veselyn Общие вопросы C/C++ 1 08.04.2010 16:36
Функция с переменным числом параметров С++ [CODER] Помощь студентам 3 22.03.2010 03:58
Функции с переменным числом параметров Matr1x Общие вопросы C/C++ 2 07.01.2010 16:55
Процедуры с переменным числом параметров Pascal Сергей089 Помощь студентам 2 04.04.2009 19:47