Variable argument lists

32 отговора 702 прегледа
#1

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 ...

Отговор
в отговор на Cakaтeka #2

Re: Variable argument lists

Е как очакваш да ти се компилира след като трябва да е int, а ти му даваш друго. Зарежи го чистото С и не си губи времето с него. Тъкмо по-малко ще те изврати. Напоследък С++ е стигнал такова ниво на абстракция с тия шаблони, че можеш да кажеш невероятни неща само с 2-3 реда.
Механизмът за предаване на променлив брой аргументи си е част от С и няма връзка с М$.

Отговор
в отговор на Cakaтeka #3

Re: Variable argument lists

И как я мислиш тая работа с броя на параметрите?
Трябва първо да понаучиш архитектурата на PC-то.

Я вышел им наперерез!
Отговор
в отговор на Colombino #4

Re: Variable argument lists

Шаблоните не стават баш за всчико - това е един случай, в който не могат да ми помогнат...

Отговор
в отговор на Cakaтeka #5

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
Отговор
в отговор на malkia #6

Не ми върши работа ...

Трябва ми вътре да пълня масив с неизвестна големина, който след това ще бъде подаден на друга функция за обработка. Да слагам NULL отзад май е единственото дето става, само дето иска преработка на много от кода ми ....

Отговор
в отговор на Cakaтeka #7

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++ в една програма.

Отговор
в отговор на Colombino #8

Re: Variable argument lists

> Зарежи го чистото С и не си губи времето с него. Тъкмо по-малко ще те изврати. Напоследък С++ е стигнал такова ниво на абстракция с тия шаблони, че можеш да кажеш невероятни неща само с 2-3 реда.

Преди 7-8 години и аз си мислех, че е дошъл краят на чистото C. Мина време и ми се отвориха очите. Всеки език си има мястото, където е най-добър. Е, ако не броим COBOL, Pascal, Basic... Те наистина извращават мисленето.

С Perl на 2-3 реда ще постигнеш още по-невероятни неща, но не мисля, че това доказва нещо.

Отговор
в отговор на Cakaтeka #9

Re: Не ми върши работа ...

> Трябва ми вътре да пълня масив с неизвестна големина, който след това ще бъде подаден на друга функция за обработка. Да слагам NULL отзад май е единственото дето става, само дето иска преработка на много от кода ми ....

Под 'неизвестна големина' предполагам имаш предвид неизвестна по време на компилиране, но известна по време на изпълнение. NULL е широко използвано решение за символни масиви, но за числа, които могат да заемат всякакви стойности, е по-добре да добавиш още един аргумент към функцията, който да указва големината на масива.

Отговор
в отговор на hoopla #10

[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
Отговор
в отговор на malkia #11

Ба, не пречи то...

> 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!

Отговор
в отговор на hoopla #12

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
Отговор
в отговор на malkia #13

А това каква булева алгебра е?

> 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++. "при мен работи" и "така ми харесва" не са валидни аргументи за заобикаляне на стандартите.

Отговор
в отговор на hoopla #14

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
Отговор
в отговор на malkia #15

Смесване на 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.

Не знам как звучи, понеже никъде не съм казал, че не могат да се смесват. Тезата ми беше, че не е _желателно_ да се смесват, понеже става боза, която е кошмар за поддържане.

Недей дава акъл наляво и надясно, че стилът и придържането към стандартите не са от значение, защото звучи <попълни си го сам>.

Отговор
в отговор на hoopla #16

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
Отговор
в отговор на hoopla #17

Re: Ба, не пречи то...

Ключовата дума е "I/O". В Случая целия проблем е в едновременното използване на _две_ различни I/O библиотеки. Което няма _нищо_ общо с това от кой език ги ползваш.

Отговор
в отговор на malkia #18

Стандарти

> Pridurzhaneto kum standart e dobre, ako utochnish za kakvo stava duma wuobshte.

Ето за какво става дума: Стандартът ти дава надеждност и предсказуемост в поведението на програмата. C и C++ са различни езици с различни стандарти и когато ги смесваш, няма гаранция, че това, което си написал, ще работи по същия начин на друга ОС, с друг компилатор, библиотеки и пр., нито дори с други версии на същите ОС, компилатор и библиотеки. Може да работи, може и да не работи, но няма гаранция, понеже си излязъл извън рамките на стандартите. Сега достатъчно ясен ли съм?

На никого не правиш услуга със съвета си, че безразборното смесване на функции от двата езика не създава проблеми.

> aide.

Ами айде де...

Отговор
в отговор на Penguin #19

Re: Ба, не пречи то...

imenno,

wupreki che i hoopla donjakude e prav - no specialno za I/O-to ne e.

tirulirutatuutuu
Отговор
в отговор на malkia #20

Кой крив, кой прав

> 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-ване на кода.

Бъди здрав.

Отговор