logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

ANSI C, funkcja ze zmienna liczba argumentow, jak ?

gmp 07 Gru 2005 10:39 4007 8
REKLAMA
  • #1 2061491
    gmp
    Poziom 19  
    Posty: 434
    Pomógł: 29
    Ocena: 28
    Chcialbym zadekalrowc funkcje ze zmienna liczba argumentow ,ale bez podawania liczby argumentow na poczatku. Jak to zrobic w C lub za pomoca makra? czy jest to mozliwe?
  • REKLAMA
  • Pomocny post
    #2 2061511
    Sam Sung
    Poziom 33  
    Posty: 2018
    Pomógł: 227
    Ocena: 596
    #include <stdarg.h>
    
    int moje_printf(const char *fmt, ...)
    {
      ... // do dostępu do argumentów używamy funkcji z nagłówka stdarg.h
    }
  • REKLAMA
  • #3 2062184
    gmp
    Poziom 19  
    Posty: 434
    Pomógł: 29
    Ocena: 28
    Sam Sung napisał:
    #include <stdarg.h>
    
    int moje_printf(const char *fmt, ...)
    {
      ... // do dostępu do argumentów używamy funkcji z nagłówka stdarg.h
    }

    Moze niedokladnie sprecyzowalem, chodzi mi o avr-gcc (nie ma tam strarg.h), i funkcje np:
    moja_funkcja(...), bo w funkcjach typu printf, moze nie wprost, ale jest przesylana liczba argumentow w stringu fmt, Fukcja a'la printf analizuje string i wie ile ma argumentow i jakiego sa typu.
    Moze mozna to jakos makrem zrobic . Liczyloby ono ilosc argumentow i wywolywalo niejawnie funkcje z dodatkowym argumentem .
  • Pomocny post
    #4 2062302
    bis
    Poziom 21  
    Posty: 274
    Pomógł: 54
    Ocena: 3
    Nie pracowałem z tym kompilatorem ale nie wierzę że brakule w nim tego standardowego elementu.
    Jeden, (dowolny!) argument jest potrzebny aby funkcje ze standardowej biblioteki <stdarg.h> mogły sie połapać jak i gdzie są pozostałe parametry. Ile ich i jakie to jest sprawa programisty i tego jak sobie to wszystko oprogramował. Przykład z printf jest trochę mylący bo pokazuje jak to jest zrobione (wskażnik do stringu z formatem) w tej konkretnej funkcji. Ty używając funkcji va_start(), va_arg() i va_end() możesz zaimplementować sobie dowolną metodę. W wielu kompilatorach jest są to makra. na początek treba użyć va_start( paramx ) gdzie paramx to OSTATNI znany argument funkcji. przykład
    
    funcvararg( int ala, char* tola, double ola,....)
    {
    va_list parg;
    
    int a,b,c;
    
    ......
    
    va_start( parg, ola);// początek pracy ze zmienną listą parametrrów
    ........
    // tu przykładowe pobieranie kolejnych parametrów Z ZAŁOŻENIEM że są typu int
    a = va_arg( parg, int );// pierwszy argumet za ola
    b = va_arg( parg, int);// drugi argument za ola
    c = va_arg( parg, int);// trzeci argument za ola
    
    .....// na koniec
    va_end(parg);
    
    
    }
    
    


    w tym przykładzie nie ma jakiejkolwiek kontroli poprawności, wszystko spoczywa na programiście i warto się trochę natrudzić aby nie dołożyć sobie pracy przy szukaniu błędów wywołania.
  • REKLAMA
  • #5 2062915
    Sam Sung
    Poziom 33  
    Posty: 2018
    Pomógł: 227
    Ocena: 596
    gmp napisał:
    chodzi mi o avr-gcc (nie ma tam strarg.h), i funkcje np:
    moja_funkcja(...)

    Takiej funkcji bez ani jednego nazwanego argumentu nie da się zrobić nawet z stdarg.h, a bez tego nagłówka nie zrobisz zupełnie nic. Żadne makro nic nie da. Zamiast tego można zadeklarować funkcję przyjmującą tablicę wartości lub (w razie potrzeby) struktur (lub unii struktur), i potem przed wywoływaniem funkcji przygotowywać takie tablice. Albo oczywiście zastanowić się, czy nie da się danego problemu rozwiązać prościej :)
  • REKLAMA
  • #6 2063101
    bis
    Poziom 21  
    Posty: 274
    Pomógł: 54
    Ocena: 3
    A tam się nieda!. Oczywiście że się da, właśnie tymi funkcjami. Dla kompilatorów które parametry przekazują przez stos można użyć właśnie tych funkcji (a w rzeczywistości makr) z <stdarg.h> W rzeczywistości operują one wkażnikami do obszarów na stosie. Trzeba tylko wywołać va_start() z parametrem zmiennej lokalnej funkcji i "odliczyć" poprawną ilość argumentów "nieważnych"(bedzie to np. adres powrotu) i mamy dostep tego co zostało odłożone na stosie w miejscu wywołania. Oczywiście jest to jazda bez trzymanki. Trzeba ignorować ostrzeżenia kompilatora(nie będzie nam durna maszyna mówiła co jest dobrze a co nie, my wiemy lepiej). Dokładnie sobie komentować co się robi. No i zerowa przenośność, Ale można, jak najbardziej. Przecież "C" pierwotnie powstał jako nakładka na makroassembler i tu właśnie z tej "pępowiny" można skorzystać. Tylko po co?
  • #7 2063302
    gmp
    Poziom 19  
    Posty: 434
    Pomógł: 29
    Ocena: 28
    Sam Sung napisał:

    moja_funkcja(...)
    Takiej funkcji bez ani jednego nazwanego argumentu nie da się zrobić ...


    Troche sie zapedzielm, oczywiscie ze chce wywolywac funkcje z jaks tam liczba argumetow, ale moze mozna to obejsc makrami. Chodzi mi o to zeby zrobic ulatweinie dla czloweika ktory bedzie uzywal programu napisanego przeze mnie , aby latwiej mu bylo cos dopisywac. np : potrzebuje "funkcji" ktora by robila logiczne AND z argumentow AND(a,b,c,....) ->i to bylo rowanowazne( a && b && c && .....) . Wiem ze mozna to zrobic wprost ,ale to tylko przyklad. Moze da sie to zrobic jakims makrem?Argumentow moze byc od 1 do kilkunastu.
  • #8 2063366
    bis
    Poziom 21  
    Posty: 274
    Pomógł: 54
    Ocena: 3
    To raczej nie wyjdzie. W standardowych kompilatorach to co nazywasz makrem to robi preprocesor ale tam niestety nie ma możliwości definicji ze zmienną ilością argumentów, nie ma też mozliwośco "przeciążania" nazw czyli zdefiniowania wszystkich możliwych "funkcji" (ta sama nazwa, ale z różnymi listami parametrów)(ani na etapie preprocesora a tym bardziej kompilacji). Preprocesor jest "jednoprzebiegowy" i różne sztuczki z dynamicznym definiowaniem nazw chyba też się tu nie nadadzą. Jak na coś wpadnę, dam znać
  • #9 2063526
    Sam Sung
    Poziom 33  
    Posty: 2018
    Pomógł: 227
    Ocena: 596
    bis napisał:
    A tam się nieda!. Oczywiście że się da, właśnie tymi funkcjami. (...) Oczywiście jest to jazda bez trzymanki. (...) No i zerowa przenośność, Ale można, jak najbardziej.

    W przypadku ogólnym, w języku C - NIE DA SIĘ.
    Na konkretniej architekturze (np. AVR) można sobie oczywiście kombinować ze stosem, ale nie jest to rozwiązanie przejrzyste, a właśnie o to chodzi autorowi wątku:
    gmp napisał:
    Chodzi mi o to zeby zrobic ulatweinie dla czloweika ktory bedzie uzywal programu napisanego przeze mnie , aby latwiej mu bylo cos dopisywac.


    gmp napisał:
    np : potrzebuje "funkcji" ktora by robila logiczne AND z argumentow AND(a,b,c,....) ->i to bylo rowanowazne( a && b && c && .....) . Wiem ze mozna to zrobic wprost ,ale to tylko przyklad. Moze da sie to zrobic jakims makrem?Argumentow moze byc od 1 do kilkunastu.

    Skoro tak, to napisz sobie te kilkanaście makr z 1 argumentem, 2 argumentami, trzema, ..., kilkunastoma. Albo zrób swój preprocesor, który będzie takie makra generował :) W końcu tak naprawdę chodzi Ci o pisanie w języku wyższego poziomu niż C...

Podsumowanie tematu

✨ Dyskusja dotyczy deklaracji funkcji w języku ANSI C z zmienną liczbą argumentów bez podawania ich liczby na początku. Standardowo do obsługi zmiennej liczby argumentów używa się nagłówka oraz makr va_start(), va_arg() i va_end(), które wymagają co najmniej jednego nazwanego argumentu jako punktu odniesienia. W przypadku kompilatora avr-gcc, który według autora nie posiada , sugerowano, że prawdopodobnie jednak jest on dostępny, a jego funkcje działają na wskaźnikach do stosu. Nie jest możliwe zdefiniowanie funkcji z całkowicie nieokreśloną liczbą argumentów bez żadnego nazwanego parametru, ani też nie da się tego osiągnąć wyłącznie za pomocą makr preprocesora, gdyż preprocesor C nie obsługuje zmiennej liczby argumentów ani przeciążania funkcji. Jako obejście proponowano tworzenie makr dla różnych liczby argumentów (np. od 1 do kilkunastu) lub przygotowywanie tablic argumentów przekazywanych do funkcji. Wskazano, że na poziomie architektury (np. AVR) można manipulować stosem, ale jest to rozwiązanie nieprzenośne i nieczytelne. Przykładem zastosowania jest funkcja realizująca logiczne AND dla zmiennej liczby argumentów, jednak jej implementacja wymaga jawnego podania liczby argumentów lub wielu makr. Podsumowując, w standardowym C bez nazwanego argumentu i bez nie da się zaimplementować funkcji z dowolną liczbą argumentów, a makra nie oferują mechanizmu liczenia argumentów ani przeciążania nazw funkcji.
Podsumowanie wygenerowane przez AI na podstawie treści dyskusji.
REKLAMA