C fuggveny hatarozatlan szamu agumentummal

Andras Tantos andras at tantosonline.com
Mon Sep 12 17:18:01 CEST 2005


Hali!

>Sziasztok,
>
> LCD-n vagy adott pozicioba, vagy a kurzor aktualis poziciojaba irnam ki
> a megadott sztringet. Ha nincs kituntetett pozicio -marad a kurzor
> aktualis helye-, akkor a fuggveny meghivasakor szeretnem elhagyni a
> koordinata parametereket. Ezzel kapcsolatban lenne 3 kerdesem:
> 1, Miert mukodik a lenti kodreszlet csak akkor, ha y-t ketszer olvasom
> ki? (egyebkent y=0)

Nem jol csinalod. Az elso va_arg hivas az elso *aktualis* parametert adja 
vissza. Azaz, ha nem adtal meg koordinatakat, akkor azok nem fognak 
szerepelni a va_arg listaban. Hogy pontosan mi szerepel benne, azt csak te 
tudhatod, a fordito nem. A normalis ...-t hasznalo fuggvenyek eseteben a nem 
opcionalis parameterek tartalmabol szoktak kitalalni a fuggvenyek futasi 
idoben, hogy minek kellene lennie a va_arg listaban, es azt hogy is kellene 
ertelmezni. Pl.:

printf("%d %s\n",3,"234");

Itt a printf eloszor elemzi a (nem opcionalis) formatum string-et, es ebbol 
derul ki szamara, hogy az elso va_arg egy int, a masodik pedig egy string 
mutato.

De ha ezt irod le:

printf("%d %s\n","234",32);

Akkor is pont ugyanez fog tortenni, csak eppen a mutato erteket fogja 
szamkent kiirni, utana pedig meg probalja a harmas cimen talalhato 
string-tombot kiirni, amibe feltehetoen bele fog halni.

> 2, Hogy lehetne megoldani, hogy elhagyott parameter eseten ne 0-t kapjak
> vissza, hanem pl. -1-et, mivel (0, 0) lenne az egyik pont az LCD-n,
> ahova szinten pozicionalni szeretnek.

Lasd fent. Valahogyan ki kell tudnod talani a fuggveny megvalositasaban, 
hogy az x, es y parameter meg volt-e adva vagy sem. Erre a modszered a nem 
opcionalis parameterek vizsgalata. Innentol kezdve persze, az, hogy mit 
csinalsz, ha x es y nincs megadva, rajtad mulik.

> 3, Lehetne-e cserelni az argumentumok sorrendjet, azaz eloszor az
> opcionalis koordinatak, majd a kiirando adat? A va_start(...)-ban a
> masodik argument az utolso fix parameter kell(ene) hogy legyen, hogy
> nezne ki ebben az esetben a va_start?

Nem. Honnan tudna a fordito, hogy a stack-en hol kezdodnek a fix 
parameterek?

> Bonusz kerdes :) :
> 4, Lokalis valtozo mindig regiszterbe kerul, nem? Van ertelme a
> "register" hasznalatanak a valtozok deklaraciojanal?

Nem kerul mindig regiszterbe. A forditon mulik. De a 'register' kulcsszonak 
valoban nem sok ertelme van (ma mar). Minden ertelmes fordito maga donti el, 
hogy mit rak regiszterbe, es mit nem. Lokalis valtozok sokszor kerulnek 
regiszterbe, de nem mindig. Es persze globalis valtozok is kerulhetnek 
regiszterbe, ha van eleg, vagy ha a fordito ugy latja jonak. AVR-en nem 
vagyok annyira otthon, de sokszor kerulnek pl. fuggveny parameterek is 
regiszterekbe.

Utoirat:

A fentiek miatt a ... hasznalata eleg bonyolult kodot szokott eredmenyezni a 
fuggveny megvalositasaban (pl. karakter string ertelmezes printf eseteben). 
Ez a nagy es bonyolult kod sok program- es adat-memoriat eszik, igy en nem 
javasolnam ennek a konstrukcionak a hasznalatat mikrokontrolleres 
kornyezetben. De persze megakadalyozni nem tudlak benne.

Ha a forditod tamogatja (C99, illetve C++ szabvany) az opcionalis 
parametereket, akkor lehet ilyet is csinalni:

void LcdPrintData(const char *data, int x=-1,int y=-1) {
    ....
}

de azt hiszem a ketfele megoldas nem keverheto:

void LcdPrintData(const char *data, int x=-1,int y=-1, ... ) { // illegalis 
fuggveny megadas
    ....
}

Udv,
Tantos Andras

>
> /ATmega128, IAR C/
>
> Koszonom a segitseget!!
>
> Udv:
>    Gyenge Zoltan
>
> void LcdPrintData(const char* data, ...)
> {
>      register unsigned char i, position, x=0, y=0, counter;
>      va_list ap;
>      va_start(ap, data);
>      if (!data) return;              // Check to make sure we have a
> good pointer
>      x = va_arg(ap,unsigned char);
>      y = va_arg(ap,unsigned char);
>      y = va_arg(ap,unsigned char);
>      if ((x>0)&&(x<21)&&(y>0)&&(y<4)) LcdGotoXY(x,y);
>      position=LcdControlRead();      // Read the actual cursor position
>      counter=0;
>
> ...
> }
> 




More information about the Elektro mailing list