Variable argument lists
32 отговора
702 прегледа
Variable argument lists
Батковци, ако имате повече опит с това я ме светнете как в тялото на такава функция мога да разбера колко са ,,произволния брой'' параметри, които са и подадени ? После - макросите va_list, va_start, va_arg, va_end само миркософтски ли са ? Според една страница първия аргумент трябвало да бъде int и той указвал колко следват след него, само дето не ще да ми се компилира, когато пусна с друг тип, а именно функцията:
void VarArg( int argc, ... )
{
int iString = 0;
va_list aString;
va_start( aString, argc );
while( iString++ < argc )
printf( "string [%d] = \"%s\"\r\n", iString, (char*) va_arg( iString, CString ) );
va_end( aString );
}
извикана
VarArg( "a", "b", "c" );
води до:
error C2664: 'VarArg' : cannot convert parameter 1 from 'class CString' to 'int'
Не помага и явното преобразуване до CString ...
void VarArg( int argc, ... )
{
int iString = 0;
va_list aString;
va_start( aString, argc );
while( iString++ < argc )
printf( "string [%d] = \"%s\"\r\n", iString, (char*) va_arg( iString, CString ) );
va_end( aString );
}
извикана
VarArg( "a", "b", "c" );
води до:
error C2664: 'VarArg' : cannot convert parameter 1 from 'class CString' to 'int'
Не помага и явното преобразуване до CString ...
Re: Variable argument lists
Е как очакваш да ти се компилира след като трябва да е int, а ти му даваш друго. Зарежи го чистото С и не си губи времето с него. Тъкмо по-малко ще те изврати. Напоследък С++ е стигнал такова ниво на абстракция с тия шаблони, че можеш да кажеш невероятни неща само с 2-3 реда.
Механизмът за предаване на променлив брой аргументи си е част от С и няма връзка с М$.
Механизмът за предаване на променлив брой аргументи си е част от С и няма връзка с М$.
Re: Variable argument lists
И как я мислиш тая работа с броя на параметрите? 

Трябва първо да понаучиш архитектурата на PC-то.
Я вышел им наперерез!
Трябва първо да понаучиш архитектурата на PC-то.
Я вышел им наперерез!
Re: Variable argument lists
Шаблоните не стават баш за всчико - това е един случай, в който не могат да ми помогнат...
Re: Variable argument lists
njama nachin da razberesh kolko parametara ti sa bili podadeni - no ima nachin da si postavjash markeri ili komandni stringove ukazwashti kolko argumenta da se wzemat - naprimer:
VarArg( const char *format, ... )
VarArg( "%s %d %p", 10, 20, 30 );
W tozi sluchai se predpolaga che VarArg taka e napisano - che bi trjabwalo da ochakwa tri (chetiri sus stringa) parametura - taka rabotjat sprintf() funkciite
Drug variant (izpolzwan wuw edin Ansi C GUI za *Nix)
windowHandle CreateWindow( const char *title, ... )
CreateWindow(
"My Window",
GUI_ARG_WINDOWPOS, 10, 12,
GUI_ARG_WINDOWSIZE, 100, 200,
GUI_ARG_COLOR, 0x12333,
GUI_ARG_USERARGS, 3 /* Number of user args */
'a', 'b', 'c' /* User Args */
GUI_ARGEND );
W tozi sluchai - prosto GUI_ARG_xxxx sa definirani enumi ili #defini - i za wseki ot tjah se znae kakvo se ochakwa - neshto kato protocol - po tozi nachin sus edno wikane na funckia - mozhe da inicializirash dosta neshta - no "protokola" ili nachina kak i kolko sa ti argumentite - ti si go opredeljash - ti si go namirash.
Ima i edin posleden no ne mnogo udoben variant
VarArg( const char *data, ... )
VarArg( "Print A blah", "sumthin else", "sumthin third", NULL );
tuka prosto po NULL razibrash che trebe da se spre
.......................
Oshte edno neshto - kogato imash FLOAT - Ansi C-to konvertira FLOAT-a winagi do DOUBLE - tova ne e prechka - samo che ako imash mashina na kojato DOUBLE-a e baven - togava mozhe malko da ti poprechi - prosto za informacia.
tirulirutatuutuu
VarArg( const char *format, ... )
VarArg( "%s %d %p", 10, 20, 30 );
W tozi sluchai se predpolaga che VarArg taka e napisano - che bi trjabwalo da ochakwa tri (chetiri sus stringa) parametura - taka rabotjat sprintf() funkciite
Drug variant (izpolzwan wuw edin Ansi C GUI za *Nix)
windowHandle CreateWindow( const char *title, ... )
CreateWindow(
"My Window",
GUI_ARG_WINDOWPOS, 10, 12,
GUI_ARG_WINDOWSIZE, 100, 200,
GUI_ARG_COLOR, 0x12333,
GUI_ARG_USERARGS, 3 /* Number of user args */
'a', 'b', 'c' /* User Args */
GUI_ARGEND );
W tozi sluchai - prosto GUI_ARG_xxxx sa definirani enumi ili #defini - i za wseki ot tjah se znae kakvo se ochakwa - neshto kato protocol - po tozi nachin sus edno wikane na funckia - mozhe da inicializirash dosta neshta - no "protokola" ili nachina kak i kolko sa ti argumentite - ti si go opredeljash - ti si go namirash.
Ima i edin posleden no ne mnogo udoben variant
VarArg( const char *data, ... )
VarArg( "Print A blah", "sumthin else", "sumthin third", NULL );
tuka prosto po NULL razibrash che trebe da se spre
.......................
Oshte edno neshto - kogato imash FLOAT - Ansi C-to konvertira FLOAT-a winagi do DOUBLE - tova ne e prechka - samo che ako imash mashina na kojato DOUBLE-a e baven - togava mozhe malko da ti poprechi - prosto za informacia.
tirulirutatuutuu
Не ми върши работа ...
Трябва ми вътре да пълня масив с неизвестна големина, който след това ще бъде подаден на друга функция за обработка. Да слагам NULL отзад май е единственото дето става, само дето иска преработка на много от кода ми ....
Re: Variable argument lists
Самият стандарт на C на ISO/IEC е платен, но последната чернова е безплатна и можеш да я намериш в мрежата. Файлът, който аз имам се казва n869.pdf. Ето какво пише в 7.15:
3 The type declared is
va_list
which is an object type suitable for holding information needed by the macros
va_start, va_arg, va_end, and va_copy.
Т.е. всички тези макроси са стандартна част от езика, не са разширение на Microsoft.
Не е добра идея обаче да смесваш C и C++ в една програма.
3 The type declared is
va_list
which is an object type suitable for holding information needed by the macros
va_start, va_arg, va_end, and va_copy.
Т.е. всички тези макроси са стандартна част от езика, не са разширение на Microsoft.
Не е добра идея обаче да смесваш C и C++ в една програма.
Re: Variable argument lists
> Зарежи го чистото С и не си губи времето с него. Тъкмо по-малко ще те изврати. Напоследък С++ е стигнал такова ниво на абстракция с тия шаблони, че можеш да кажеш невероятни неща само с 2-3 реда.
Преди 7-8 години и аз си мислех, че е дошъл краят на чистото C. Мина време и ми се отвориха очите. Всеки език си има мястото, където е най-добър. Е, ако не броим COBOL, Pascal, Basic... Те наистина извращават мисленето.
С Perl на 2-3 реда ще постигнеш още по-невероятни неща, но не мисля, че това доказва нещо.
Преди 7-8 години и аз си мислех, че е дошъл краят на чистото C. Мина време и ми се отвориха очите. Всеки език си има мястото, където е най-добър. Е, ако не броим COBOL, Pascal, Basic... Те наистина извращават мисленето.
С Perl на 2-3 реда ще постигнеш още по-невероятни неща, но не мисля, че това доказва нещо.
Re: Не ми върши работа ...
> Трябва ми вътре да пълня масив с неизвестна големина, който след това ще бъде подаден на друга функция за обработка. Да слагам NULL отзад май е единственото дето става, само дето иска преработка на много от кода ми ....
Под 'неизвестна големина' предполагам имаш предвид неизвестна по време на компилиране, но известна по време на изпълнение. NULL е широко използвано решение за символни масиви, но за числа, които могат да заемат всякакви стойности, е по-добре да добавиш още един аргумент към функцията, който да указва големината на масива.
Под 'неизвестна големина' предполагам имаш предвид неизвестна по време на компилиране, но известна по време на изпълнение. NULL е широко използвано решение за символни масиви, но за числа, които могат да заемат всякакви стойности, е по-добре да добавиш още един аргумент към функцията, който да указва големината на масива.
[OT] C i C++ w edno nikomu ne prechi
smeswaneto na C i C++ nikomu ne prechi :)
Naprimer C standartnite biblioteki mogat da se polzwat ot C++ bez problem.
Ima edno neskrito pravilo - pishi bibliotekite na C, ostanaloto na C++ - zwuchi malko stranno - no C ima izchisteno ABI, dokato C++ njama. I oshte bilbioteka napisana na C (ili na C++ no sus extern "C" funkcii) lesno shte se izpolzwa ot drug ezik - dokato pod C++ njama kak (imash razlichno manglavane na imenata i klasovete - i e pulna kasha)
tirulirutatuutuu
Naprimer C standartnite biblioteki mogat da se polzwat ot C++ bez problem.
Ima edno neskrito pravilo - pishi bibliotekite na C, ostanaloto na C++ - zwuchi malko stranno - no C ima izchisteno ABI, dokato C++ njama. I oshte bilbioteka napisana na C (ili na C++ no sus extern "C" funkcii) lesno shte se izpolzwa ot drug ezik - dokato pod C++ njama kak (imash razlichno manglavane na imenata i klasovete - i e pulna kasha)
tirulirutatuutuu
Ба, не пречи то...
> smeswaneto na C i C++ nikomu ne prechi :)
[линк]:
Mixing of C++ "cout <<" like I/O syntax with C stype "printf" I/O syntax will generate strange behavior in the ordering of the user's I/O messages. To fix this insert the following call to the I/O Streams library of C++ at the start of your main program.
ios::sync_with_stdio(); Synchronize C++ and C I/O subsystems!
[линк]:
Mixing of C++ "cout <<" like I/O syntax with C stype "printf" I/O syntax will generate strange behavior in the ordering of the user's I/O messages. To fix this insert the following call to the I/O Streams library of C++ at the start of your main program.
ios::sync_with_stdio(); Synchronize C++ and C I/O subsystems!
Re: Ба, не пречи то...
pich, ti spomenawash edin stranichen efekt - zaradi edin stranichen efekt - ne mozhe da zakljuchish che C i C++ ne mogat da wurwjat ruka za ruka. Tova ne e booleva algebra...
i tuka horata kazwat mixing C++ "cout <<" and C "printf" a ne mixing C++ and C - pravish li razlika?
Az nikoga ne sum izpolzwal iostreams ili "cout <<" ili "cin >>" - lichno az gi namiram za protivni (lichno az).
i pak Syncrhonize C++ and C I/O subsystems! - ami ako si imash subsystemi koito weche sa syncrhoniznati - napisani ot pochti nachalo?
wuobshte ne si pravi takiva zakljuchenia - C i C++ si wurwjat mnogo dobre - ako zhelaesh - bi mogul C++ i C++ da napravish da ne vurvjat - naprimer napishi si na C++ printf i go napravi taka che da ne se syncronizira sus C++ "cout <<" i togava vizh - a PARADOX? a?
aide :)
tirulirutatuutuu
i tuka horata kazwat mixing C++ "cout <<" and C "printf" a ne mixing C++ and C - pravish li razlika?
Az nikoga ne sum izpolzwal iostreams ili "cout <<" ili "cin >>" - lichno az gi namiram za protivni (lichno az).
i pak Syncrhonize C++ and C I/O subsystems! - ami ako si imash subsystemi koito weche sa syncrhoniznati - napisani ot pochti nachalo?
wuobshte ne si pravi takiva zakljuchenia - C i C++ si wurwjat mnogo dobre - ako zhelaesh - bi mogul C++ i C++ da napravish da ne vurvjat - naprimer napishi si na C++ printf i go napravi taka che da ne se syncronizira sus C++ "cout <<" i togava vizh - a PARADOX? a?
aide :)
tirulirutatuutuu
А това каква булева алгебра е?
> wuobshte ne si pravi takiva zakljuchenia - C i C++ si wurwjat mnogo dobre - ako zhelaesh - bi mogul C++ i C++ da napravish da ne vurvjat - naprimer napishi si na C++ printf i go napravi taka che da ne se syncronizira sus C++ "cout <<" i togava vizh - a PARADOX? a?
На всеки език можеш да напишеш нещо, което не работи. Никак не е трудно и никакви познания не се изискват. Как обаче можеш да го използваш като доказателство за взаимодействието му с друг език, не ми е ясно.
printf е стандартна част от C, cout е стандартна част от C++. "при мен работи" и "така ми харесва" не са валидни аргументи за заобикаляне на стандартите.
На всеки език можеш да напишеш нещо, което не работи. Никак не е трудно и никакви познания не се изискват. Как обаче можеш да го използваш като доказателство за взаимодействието му с друг език, не ми е ясно.
printf е стандартна част от C, cout е стандартна част от C++. "при мен работи" и "така ми харесва" не са валидни аргументи за заобикаляне на стандартите.
Re: А това каква булева алгебра е?
>> На всеки език можеш да напишеш нещо, което не работи. Никак не е трудно и никакви познания не се изискват. Как обаче можеш да го използваш като доказателство за взаимодействието му с друг език, не ми е ясно.
Pokazah ti s primer che njama znachenie printf na kakvo e napisan - problema e drugade - ne wuw printf ili cout - a w tozi spomenata ot tebe syncrhonizatzia - problema dori mozhe da e mnogo maluk i da se poluchawa samo s opredeleni run-time biblioteki na dadeni kompilatori - mozhe i za wsihcki da e taka - neznam - az iostreams ne polzwam.
Ako iskash spazwaj si standartite - ot tova njama da spechelish obache mnogo - ponjakoga edin 'printf' e dosta po-nagleden i tochen otkolkoto razni "cout <<" - koito stavat dori dosta nechetlivi i generirat uzhasno mnogo poveche kod i razpokusani stringove.
Sus edin "printf" ili "sprintf" mozhe da si imash predvaritelno zapisani suobshtenia kato resurs i ot tam da gi loadwash i sled tova pokazwash kato im zadawash parametri - razbira se mozhe da si napishesh po-dobra i sigurna tvoja versia.
nedej dava akul na horata naljavo nadjasno che C i C++ ne moje da se mesi - zwuchi glupavo i naivno - i dokazatelstwo ako reshish sam mozhe da si napravish.
Tova koeto iskash ti da kazhesh e che ne trjabwa da se smeswa "C printf" sus "C++ cout" i e dosta razlichno ot obobshtawaneto C i C++ ne moje da se smeswat...
i spolai ti sus standarta ;)
tirulirutatuutuu
Pokazah ti s primer che njama znachenie printf na kakvo e napisan - problema e drugade - ne wuw printf ili cout - a w tozi spomenata ot tebe syncrhonizatzia - problema dori mozhe da e mnogo maluk i da se poluchawa samo s opredeleni run-time biblioteki na dadeni kompilatori - mozhe i za wsihcki da e taka - neznam - az iostreams ne polzwam.
Ako iskash spazwaj si standartite - ot tova njama da spechelish obache mnogo - ponjakoga edin 'printf' e dosta po-nagleden i tochen otkolkoto razni "cout <<" - koito stavat dori dosta nechetlivi i generirat uzhasno mnogo poveche kod i razpokusani stringove.
Sus edin "printf" ili "sprintf" mozhe da si imash predvaritelno zapisani suobshtenia kato resurs i ot tam da gi loadwash i sled tova pokazwash kato im zadawash parametri - razbira se mozhe da si napishesh po-dobra i sigurna tvoja versia.
nedej dava akul na horata naljavo nadjasno che C i C++ ne moje da se mesi - zwuchi glupavo i naivno - i dokazatelstwo ako reshish sam mozhe da si napravish.
Tova koeto iskash ti da kazhesh e che ne trjabwa da se smeswa "C printf" sus "C++ cout" i e dosta razlichno ot obobshtawaneto C i C++ ne moje da se smeswat...
i spolai ti sus standarta ;)
tirulirutatuutuu
Смесване на C и C++
> nedej dava akul na horata naljavo nadjasno che C i C++ ne moje da se mesi - zwuchi glupavo i naivno - i dokazatelstwo ako reshish sam mozhe da si napravish.
Не знам как звучи, понеже никъде не съм казал, че не могат да се смесват. Тезата ми беше, че не е _желателно_ да се смесват, понеже става боза, която е кошмар за поддържане.
Недей дава акъл наляво и надясно, че стилът и придържането към стандартите не са от значение, защото звучи <попълни си го сам>.
Не знам как звучи, понеже никъде не съм казал, че не могат да се смесват. Тезата ми беше, че не е _желателно_ да се смесват, понеже става боза, която е кошмар за поддържане.
Недей дава акъл наляво и надясно, че стилът и придържането към стандартите не са от значение, защото звучи <попълни си го сам>.
Re: Смесване на C и C++
kakto i da e - ne sum kazwal nishto za stil, a poddurzhaneto na stil se naricha moda - a poslednata si se meni.
Pridurzhaneto kum standart e dobre, ako utochnish za kakvo stava duma wuobshte.
aide.
tirulirutatuutuu
Pridurzhaneto kum standart e dobre, ako utochnish za kakvo stava duma wuobshte.
aide.
tirulirutatuutuu
Re: Ба, не пречи то...
Ключовата дума е "I/O". В Случая целия проблем е в едновременното използване на _две_ различни I/O библиотеки. Което няма _нищо_ общо с това от кой език ги ползваш.
Стандарти
> Pridurzhaneto kum standart e dobre, ako utochnish za kakvo stava duma wuobshte.
Ето за какво става дума: Стандартът ти дава надеждност и предсказуемост в поведението на програмата. C и C++ са различни езици с различни стандарти и когато ги смесваш, няма гаранция, че това, което си написал, ще работи по същия начин на друга ОС, с друг компилатор, библиотеки и пр., нито дори с други версии на същите ОС, компилатор и библиотеки. Може да работи, може и да не работи, но няма гаранция, понеже си излязъл извън рамките на стандартите. Сега достатъчно ясен ли съм?
На никого не правиш услуга със съвета си, че безразборното смесване на функции от двата езика не създава проблеми.
> aide.
Ами айде де...
Ето за какво става дума: Стандартът ти дава надеждност и предсказуемост в поведението на програмата. C и C++ са различни езици с различни стандарти и когато ги смесваш, няма гаранция, че това, което си написал, ще работи по същия начин на друга ОС, с друг компилатор, библиотеки и пр., нито дори с други версии на същите ОС, компилатор и библиотеки. Може да работи, може и да не работи, но няма гаранция, понеже си излязъл извън рамките на стандартите. Сега достатъчно ясен ли съм?
На никого не правиш услуга със съвета си, че безразборното смесване на функции от двата езика не създава проблеми.
> aide.
Ами айде де...
Re: Ба, не пречи то...
imenno,
wupreki che i hoopla donjakude e prav - no specialno za I/O-to ne e.
tirulirutatuutuu
wupreki che i hoopla donjakude e prav - no specialno za I/O-to ne e.
tirulirutatuutuu
Кой крив, кой прав
> wupreki che i hoopla donjakude e prav - no specialno za I/O-to ne e.
Ок, справедливостта изисква да кажа, че като се замислих, има голям резон да си пишеш библиотеките на C, макар да ги викаш от C++. Който следи mailing list-а на gcc знае, че ABI (Application Binary Interface) на C++ в gcc от доста време е в процес на преработка и в резултат на това програмите, писани на различните версии не се линкват с обектни модули и библиотеки, компилирани с други версии. 3.1 е несъвместим с 2.95, на път е да излезе 3.2, несъвместим с предишните, като още от сега заявяват, че не е сигурно, че и новото ABI няма да се наложи да се преправя. Докато ABI на C, вероятно по исторически причини, а и затова, че е по-малък език, е стабилен.
Продължавам да смятам обаче, че е за предпочитане да се използват вградените средства на езика, на който пишеш, ако не за друго, то за по-лесно четене и debug-ване на кода.
Бъди здрав.
Ок, справедливостта изисква да кажа, че като се замислих, има голям резон да си пишеш библиотеките на C, макар да ги викаш от C++. Който следи mailing list-а на gcc знае, че ABI (Application Binary Interface) на C++ в gcc от доста време е в процес на преработка и в резултат на това програмите, писани на различните версии не се линкват с обектни модули и библиотеки, компилирани с други версии. 3.1 е несъвместим с 2.95, на път е да излезе 3.2, несъвместим с предишните, като още от сега заявяват, че не е сигурно, че и новото ABI няма да се наложи да се преправя. Докато ABI на C, вероятно по исторически причини, а и затова, че е по-малък език, е стабилен.
Продължавам да смятам обаче, че е за предпочитане да се използват вградените средства на езика, на който пишеш, ако не за друго, то за по-лесно четене и debug-ване на кода.
Бъди здрав.