/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
udefineret antal argumenter til en funktio~
Fra : Peter Sørensen


Dato : 25-11-02 16:40

En funktion som printf kan tage et vilkårligt antal parametre, fra en til x.
Den erklæres som bekendt som printf(char *string,...) hvor ... angiver de
optionelle parametre, men hvis man selv laver en tilsvarende funktion,
hvordan får man så fat i de paramtere.

Jeg har lavet en implementation hvor jeg med inline assembler piller en
værdi ud fra stacken når jeg ved den findes (alla %x i printf), men det er
lidt klumpet og c må jo have en syntax for det selv.

Hvordan er det så man gør det i c uden inline asm?



 
 
Igor V. Rafienko (25-11-2002)
Kommentar
Fra : Igor V. Rafienko


Dato : 25-11-02 17:03

[ Peter Sørensen ]

[ ... ]

> Den erklæres som bekendt som printf(char *string,...) hvor ... angiver de
> optionelle parametre, men hvis man selv laver en tilsvarende funktion,
> hvordan får man så fat i de paramtere.


<URL:http://www.eskimo.com/~scs/C-faq/s15.html>





ivr
--
<peder> igorr: tcl ja... det er fra de dypeste avgrunnene i helvete det...
<peder> php er bare fra foajeen
            -- pederst på irc

Peter Sørensen (26-11-2002)
Kommentar
Fra : Peter Sørensen


Dato : 26-11-02 15:39

> <URL:http://www.eskimo.com/~scs/C-faq/s15.html>

Takker for det hurtige svar.Der er dog en ting mere som jeg er i tvivl om.
Da den beskrevne metode henter argumenterne ud som void pointers, så kan jeg
ikke se om argumentet et en signed/unsigned char, short int eller long int
(eller andre typer for den sagsskyld). Printf ser at der er et argument som
er heltal når den møder %d, men hvordan kan man, som printf, se hvilken
slags heltal der er tale om?
Hvis funktionen kaldes med en char, jeg får en void pointer til den og
typecaster den til en long int, så er problemet der.

Hvad er løsningen på det?
Jeg kan naturligvis lave et formateringssystem alla %dui betydende unsigned
int, men da det virker som om printf kan klare sig uden, ville jeg høre om
nogen kender til en mere elegant løsning.



Igor V. Rafienko (26-11-2002)
Kommentar
Fra : Igor V. Rafienko


Dato : 26-11-02 16:06

[ Peter Sørensen ]

[ ... ]


> Takker for det hurtige svar.Der er dog en ting mere som jeg er i
> tvivl om. Da den beskrevne metode henter argumenterne ud som void
> pointers, så kan jeg ikke se om argumentet et en signed/unsigned
> char, short int eller long int (eller andre typer for den
> sagsskyld).


Nettopp. C har ingen generisk "apply" (slik som fx. CL).


> Printf ser at der er et argument som er heltal når den møder %d, men
> hvordan kan man, som printf, se hvilken slags heltal der er tale om?


Via format spesifikasjonen. Unsigned tall har "u" et passende sted
(%u, %hu, %lu, fx.). I og med at sizeof( unsigned T ) == sizeof(
signed T ), så er det kun vår interpretasjon av bitmønsteret som
skjuler seg bak T, som avgjør hva argumentet representerer.

[ ... ]


> Jeg kan naturligvis lave et formateringssystem alla %dui betydende
> unsigned int, men da det virker som om printf kan klare sig uden,
> ville jeg høre om nogen kender til en mere elegant løsning.


Det finnes ingen mer elegant løsning (ikke med mindre du lager din
egen "variadic" type, som innkapsler verdien og typen i seg. Jeg er
dog ikke sikker på hvorvidt det kommer til å bli mer elegant enn den
eksisterende løsningen (via void* og format-beskrivelsen à la
printf)).





ivr
--
<peder> igorr: tcl ja... det er fra de dypeste avgrunnene i helvete det...
<peder> php er bare fra foajeen
            -- pederst på irc

Byrial Jensen (26-11-2002)
Kommentar
Fra : Byrial Jensen


Dato : 26-11-02 20:27

Peter Sørensen <spam_ps@mail.tele.dk> skrev:
>> <URL:http://www.eskimo.com/~scs/C-faq/s15.html>
>
> Takker for det hurtige svar.Der er dog en ting mere som jeg er i tvivl om.
> Da den beskrevne metode henter argumenterne ud som void pointers,

Du skal selv vide typen af argumentet og angive den som anden
argument i va_arg makroen.

> så kan jeg
> ikke se om argumentet et en signed/unsigned char, short int eller long int
> (eller andre typer for den sagsskyld).

Argumentet kan aldrig være en char eller short int. Det skyldes at
C laver "default argument promotions" ved funktionskald når
argumenttyperne ikke er angivet i en prototype.

> Printf ser at der er et argument som
> er heltal når den møder %d, men hvordan kan man, som printf, se hvilken
> slags heltal der er tale om?

printf()-funktionerne bruger en length modifier (hh = char, h =
short, l = long, ll = long long, j = intmax_t, z = size_t, t =
ptrdiff_t, L = long double) i formatstrengen til at angive
størrelsen. De typer som er kortere end en int, konverteres ved
funktionskaldet til int-størrelse, men konverteres tilbage af
printf().

> Hvis funktionen kaldes med en char, jeg får en void pointer til den og
> typecaster den til en long int, så er problemet der.

Ja, det giver udefineret adfærd og er uportabelt hvis det måtte virke
nogetsteds.

> Hvad er løsningen på det?

Skriv "int" som type i va_arg hvis funktionen er kaldt med en char,
da en char bliver konverteret til en int ved kaldet.

> Jeg kan naturligvis lave et formateringssystem alla %dui betydende unsigned
> int, men da det virker som om printf kan klare sig uden, ville jeg høre om
> nogen kender til en mere elegant løsning.

printf() klarer sig ikke uden. Læs om hvordan printf()'s
formatstreng er opbygget med felter til flag, bredde, præcison,
længde, type i din manual, lærebog eller hvad du nu har.

--
Skal musik- og edb-industrien have ret til fratage forbrugerne deres
rettigheder i henhold til Ophavsretloven, begrænse konkurrencen og
fremme monopoldannelse ved hjælp af tekniske midler? Sig nej! Nu!
Støt underskriftsindsamlingen på http://www.digitalforbruger.dk

Søg
Reklame
Statistik
Spørgsmål : 177491
Tips : 31966
Nyheder : 719565
Indlæg : 6408458
Brugere : 218886

Månedens bedste
Årets bedste
Sidste års bedste