• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Sandbox 4 - Funkcje ze zmienną ilością argumentów
#1
Witam w kolejnej odsłonie :-)
Tym razem we wiaderku mam łopatkę celem przekopania tematu zastosowania funkcji ze zmienną ilością argumentów.
Pomysł ten urodził się podczas pisania kodu dla jednego z naszych kolegów. Potrzebowałem funkcji, w której będę mógł dowolnie zmieniać ilość argumentów.
Do czego to może być przydatne?
Na przykład do sterowania danymi wyświetlanymi na naszym LCD.
Wymagania są dość wygórowane - nie wiem ile linii ma wyświetlacz i nie mam pojęcia co trzeba będzie wyświetlić w każdej linii. A chciałbym mieć funkcję, w której będę mógł sterować miejscem i typem danych do wyświetlenia.
Na szczęście specyfikacja języka C pozwala na taką konstrukcję - czyli funkcję ze zmienną ilością argumentów.
Przykład - zamiast:

Kod:
float temperatura=23.45;
int x=56;
lcd.setCursor(0,0);
lcd.print("Temp.");
lcd.setCursor(7,0);
lcd.print(temperatura);
lcd.setCursor(12,0);
lcd.print(" F");
lcd.setCursor(0,1);
lcd.print("Ustawiono");
lcd.setCursor(11,1);
lcd.print(x);
 
... za pomocą naszej funkcji możemy napisać:-)
Kod:
float temperatura=23.45;
int x=56;
ekran("IISIIDIISIISIID",0,0,"Temp.",7,0,temperatura,12,0," F",0,1,"Ustawiono",11,1,x);
Huh Prawda, że na pierwszy rzut oka nieco zawiłe?
Funkcja ekran - jest właśnie przykładem funkcji ze zmienną ilością argumentów.
Cały dowcip polega na tym, że najpierw definiujemy tzw. "ciąg formatujący" a potem wstawiamy dane do wyświetlenia, zgodnie z tym ciągiem właśnie :-)
Co zyskuję - możliwość formatowania danych do wyświetlenia za pomocą jednej linii kodu.
Co tracę - kilkadziesiąt bajtów, bo trzeba do naszego kodu wkleić ciało tej przykładowej funkcji: 
Kod:
// --- uniwersalna funkcja ekran ... by wojtekizk -------------------
void ekran(const char typ[] ...)
{
int kol,wiersz;
int ile=1;
int i = 0;
int ival=0;
double dval=0;
char c;
char *sval;
va_list ap;
va_start(ap,typ);
lcd.clear();
 while((c = typ[i++])!='\0')
    {
    switch (c)
      {
       case 'I':
                ival = va_arg(ap,int);
                if(ile==1) {kol=ival;}
                if(ile==2) {wiersz=ival;}
                ile++;if(ile>2){ile=1;lcd.setCursor(kol,wiersz);}
                break;
       case 'D':
                dval = va_arg(ap,double);
                lcd.print(dval);
                break;
       case 'S':
                sval = va_arg(ap,char*);
                lcd.print(sval);
                break;
       default:
                lcd.clear();
                lcd.print(" Bledny format !");
                lcd.setCursor(0,1);lcd.print(typ);
       }
    }
va_end(ap);
}

Na życzenie mogę dokładnie opisać jakie "czary" tu się robi. Myślę jednak, że da się wykumać o co tu biega :-)
Przykłady wywołań (robię właśnie menu do obsługi 3 akwariów dla naszego kolegi):
Kod:
ekran("IISIISIISIIS",0,0,"<TEMP.>",9,0,"OSWIE.",0,1," WENT.",9,1,"TIMER");
ekran("IISIIS",0,0,"   TEMPERATURA",0,1," < Wylaczenia >");
ekran("IISIISIISIID",0,0,"< OK USTAWIONO >",1,1,s,8,1,"= ",10,1,t);
Trochę trudne do ogarnięcia ale można się przyzwyczaić :-)
Pozdrawiam
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości