Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1] 2  Все   Вниз
  Печать  
Автор Тема: неизвестное количество параметров  (Прочитано 18254 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Алексей++
кот глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« : 04-03-2010 15:38 » 

вопрос у меня заключается в том, как передать все параметры дальше?

например
Код:
void TRACE(const char* f, ...)
{
   ....
}

//отсюда вызовется TRACE
void MyTRACE(const char* f, ...)
{
TRACE(f,    ?    ); //как ?
}


main()
{
   MyTRACE("%d%d",1,2);
}
« Последнее редактирование: 04-03-2010 16:12 от Алексей1153++ » Записан

darkelf
Молодой специалист

ua
Offline Offline

« Ответ #1 : 04-03-2010 16:07 » 

Посмотрите в сторону stdarg.h в частности va_start() и va_end(), но, правда, тогда void TRACE() и void MyTRACE() должны будут иметь следующий вид:
Код:
void TRACE(const char* f, va_list va)
{
...
}

void MyTRACE(const char* f, ...)
{ va_list va;
  va_start(va, f);
  TRACE(f,  va);
  va_end(va);
}
Записан
Алексей++
кот глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #2 : 04-03-2010 16:23 » 

компилятор пропустил, но TRACE выводит левщину

видимо,  TRACE(f,  va); - надо что-то иначе сделать
Записан

darkelf
Молодой специалист

ua
Offline Offline

« Ответ #3 : 04-03-2010 16:40 » 

если в TRACE() используется fprintf(), например, то его заменить на vfprintf(), которому и передать оный va, аналогично и для других функций.
Записан
Алексей++
кот глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #4 : 04-03-2010 16:47 » 

дело то не в том, что используется в TRACE()

(а там
Код:
va_list ptr; va_start(ptr, pszFmt);
ATL::CTrace::s_trace.TraceV(m_pszFileName, m_nLineNo, atlTraceGeneral, 0, pszFmt, ptr);
va_end(ptr);
)

а хочется универсально передать параметры. Нужно как-то подсунуть данные в стек по хитрому - я не могу пока сообразить, как

Ну а ATL::CTrace::s_trace.TraceV - это просто костыль, он ожидает именно va_list и с ним работает дальше
Записан

Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #5 : 04-03-2010 20:03 » 

Лёш, я не понял. Проблема с кучей параметров? Или же всё-таки нужна ф-я с переменным числом параметров?
В первом случае передавай один параметр - список.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Алексей++
кот глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #6 : 04-03-2010 20:23 » 

Джон, хочется понять, как каскадно передавать список параметров
Записан

darkelf
Молодой специалист

ua
Offline Offline

« Ответ #7 : 05-03-2010 05:53 » 

дело то не в том, что используется в TRACE()

(а там
Код:
va_list ptr; va_start(ptr, pszFmt);
ATL::CTrace::s_trace.TraceV(m_pszFileName, m_nLineNo, atlTraceGeneral, 0, pszFmt, ptr);
va_end(ptr);
)

а хочется универсально передать параметры. Нужно как-то подсунуть данные в стек по хитрому - я не могу пока сообразить, как

Ну а ATL::CTrace::s_trace.TraceV - это просто костыль, он ожидает именно va_list и с ним работает дальше
тогда вместо TRACE напрямую вызывайте  ATL::CTrace::s_trace.TraceV() и будет Вам счастье.
Насколько я знаю, ничего, кроме va_list, для передачи переменного числа параметров в C не придумали.
« Последнее редактирование: 05-03-2010 06:18 от darkelf » Записан
Алексей++
кот глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #8 : 05-03-2010 06:41 » 

darkelf, та нет, дело не в TRACE , это как общееизвестный пример функции я взял. Мне хочется общее решение

Цитата
Насколько я знаю, ничего, кроме va_list, для передачи переменного числа параметров в C не придумали.
вот и эхъ
Записан

Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #9 : 05-03-2010 07:06 » 

Джон, хочется понять, как каскадно передавать список параметров

Хммм как-то понятней не стало. Что в данном случае значит "каскадно"?

Вот смотри, например, что я имею ввиду. Есить у нас один товарищ, который практически не программирует, но всегда больше всех знает, так у него в любой ф-ции (сложной) 1в качестве параметра выступает DataTable (C#). Вот и всё.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Алексей++
кот глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #10 : 05-03-2010 07:35 » 

ну что непонятного - к примеру, имеется некая функция
int F(...);


требуется тупо захучить её
Код:
int MyF1(...)
{
    return MyF2( как-то передали параметры );
}

int MyF2(...)
{
    return F( как-то передали параметры );
}

(у себя я сделал иначе, а сабж - это уже из чистого интереса - как это провернуть?)


Цитата
так у него в любой ф-ции (сложной) 1в качестве параметра выступает DataTable (C#).
а зачем ? Я не знаю, что за тип это. У меня, кстати, не шарп же ))
Записан

Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #11 : 05-03-2010 07:44 » 

Не, Лёш, эт понятно, что не шарп. Идея такая, что передаётся контейнер. В С# DataTable - это просто таблица данных. Каждый столбец этой таблицы (в данном случае) является параметром и может быть любого типа. Таким образом ты всегда можешь добавить ещё параметров в уже существующую ф-ю, не меняя при этом интерфейса.
Вот и всё.  И в твоём случае я думаю, что тебе надо передавать контейнер, забитый нужными параметрами. Вот и всё.
Ф-я  с переменным количеством параметров реально необходима самому программеру для удобства, а не для решения неких логических или алгоритмических задач. Скажем так, я не знаю ни одной ситуации, где бы без таких ф-ций нельзя было бы обойтись.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Алексей++
кот глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #12 : 05-03-2010 08:08 » 

Джон, ну я так делал для передачи табличных данных из базы, когда клиенту самому не надо давать напрямую подключаться к базе ) Таблицу в текстовом виде.

Я так понимаю, задача сабжа без ассемблерной вставки не решается. Ну и ладно, обойдусь Улыбаюсь
Записан

clearance
Гость
« Ответ #13 : 10-03-2010 03:30 » 

Код:

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

void MyTRACE(const char *f, ...);

int main(void) /* ANSI C89 */
{
    MyTRACE("%d%d", 1, 2);

    exit(EXIT_SUCCESS);
}

void TRACE(const char *f, va_list *p)
{
    vprintf(f, *p);
}

void MyTRACE(const char *f, ...)
{
    va_list ap1;
   
    va_start(ap1, f);

    vprintf(f, ap1);
   
    TRACE(f, &ap1);
   
    va_end(ap1);
}
Записан
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #14 : 10-03-2010 03:56 » 

clearance, +1
я также делаю
Записан

Странно всё это....
Алексей++
кот глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #15 : 10-03-2010 04:38 » 

да это уже ясно, но вопрос то не про конкретно вывод был Отлично А про общий случай
Записан

Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #16 : 10-03-2010 04:55 » 

ну собственно по аналогии, передаёшь va_list во все подфункции
Записан

Странно всё это....
Алексей++
кот глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #17 : 10-03-2010 05:05 » 

ну собственно по аналогии, передаёшь va_list во все подфункции
ну само собой. Но, если только они умеют принимать va , а не сами выглядят как F(...) Улыбаюсь
Записан

RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #18 : 10-03-2010 10:27 » 

Леш, заметь, что один обязательный параметр быть должен - это как точка отстчета и как носитель информации о количестве параметров в va_list.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Алексей++
кот глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #19 : 10-03-2010 10:40 » 

а это автоматом получится - ведь что-то нужно в va_start подставить )

А вот, к примеру, я делал заглушку функции (не применительно к САБЖ, а для других целей)
Код:
#ifdef XXXXX
CString F(int n,CString& s,BYTE by)
{
   ...
   ...
}
#else
CString F(...){return "";}
#endif

тут параметр не нужен Улыбаюсь
« Последнее редактирование: 10-03-2010 10:41 от Алексей1153++ » Записан

Serg79
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #20 : 10-03-2010 13:08 » 

ну само собой. Но, если только они умеют принимать va , а не сами выглядят как F(...) Улыбаюсь
Все функции в "стандартно библиотек C"  которые принимают переменное количество параметров ( 'F(arg, ...)' ) имеют так же свои аналоги принимающие параметры через 'va_list' ( 'vF(arg, va_list)' ). В связи с этим, при использовании библиотечных функции никогда не возникает проблем передачи переменного количества параметров ниже по цепочке.

Алексей1153++, если ты так же не хочешь в будущем столкнуться с подобной проблемой (а по моему ты с ней уже столкнулся), то при реализации функций с переменным количеством параметров, позаботься так же о реализации той же самой функции которая могла бы принимать параметры в виде списка 'va_list'.
Записан
Алексей++
кот глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #21 : 10-03-2010 15:52 » 

учту )
Записан

clearance
Гость
« Ответ #22 : 17-03-2010 07:58 » 

Код:
[guest@station tmp]$ .ansi t.c -o t
[guest@station tmp]$ ./t
1212[guest@station tmp]$ .ansi t.c -o t
t.c: In function ‘MyTRACE’:
t.c:28: предупреждение: passing argument 2 of ‘TRACE’ from incompatible pointer type
[guest@station tmp]$ ./t
12-1076278828-1076278808[guest@station tmp]$
это incompatible, когда просто va_list
Записан
Алексей++
кот глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #23 : 17-03-2010 08:07 » 

clearance, ты о чём ?
Записан

clearance
Гость
« Ответ #24 : 18-03-2010 01:58 » 

а, всё переписал
incompatible pointer type - это тип поменял, а взятие адреса забыл убрать
нормально без указателя

Код:

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

void f(const char *f, ...);
void f1(const char *f, va_list);

int main(void) /* ANSI C89 */
{
    f("%d %s %d" "\n", 1, "abcd", 2);
   
    exit(EXIT_SUCCESS);
}

void f(const char *f, ...)
{
    va_list ap;
   
    va_start(ap, f);

    f1(f, ap);
   
    va_end(ap);
}

void f1(const char *f, va_list a)
{
    vprintf(f, a);
}

Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #25 : 18-03-2010 04:58 » 

clearance, где возврат из main?
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
clearance
Гость
« Ответ #26 : 18-03-2010 09:07 » 

exit юзаю
Записан
resource
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #27 : 18-03-2010 10:11 » 

exit это не есть гуд. Лучше использовать return. В данном конкретном случае от exit вроде бы никто не страдает, но зачем порождать у себя такую привычку.
Записан
clearance
Гость
« Ответ #28 : 19-03-2010 03:24 » 

давай пример, чтобы пострадать
exit у меня, чтобы выходить из программы где угодно
Записан
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #29 : 19-03-2010 06:08 » 

только не делай этого в многопоточных приложения
Записан

Странно всё это....
Страниц: [1] 2  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines