Wie geschickt 48 Parameter an Funktion übergeben



  • Brooks schrieb:

    Design:
    Das ist in der Tat schlecht. Aber wurde nun mal so gemacht, und mir jetzt so in die Hand gedrückt. 🙂

    Nimm einen Baseballschläger, geh zum ursprünglichen Designer und füge ihm massive Schmerzen zu.



  • @Tim:
    lol. Ich weiß nicht ob es reichen würde. 🙂 Am liebsten nehme ich gleich Schaufel mit, um ihn zu vergraben.

    Es wurde so gemacht, dass die Parameter für bestimmten Platz im Char Array stehen. Bit0 im Byte0 des chararray ist z.b 0, Bit7 im Byte0 ist 7 usw.

    Die Funktion sieht so aus:

    my_func(param0,...param47)
    {
        array[47]={param0,...,param47};
    
        for(int a=0, a<48, a++)
        {
            byteNr = array[a]/8;
            bitNr = (arry[a]-byteNr*8);
            chararry[byteNr] |=(1<<bitNr);    
        }
    }
    

    Blöd ist, dass die Funktion schon lange benutz wird und ich sie nicht beliebig ändern kann:
    - die Parameter müssen unsigned short sein
    - Parameterzahl muss variabel sein

    Deshalb dachte ich an sowas wie ":". Zwar nicht unbeding super elegant. Aber wäre schelle Lösung mit deutlichen Hilfe. Aber ok. Ich überlege mir was bessrees.



  • Darfst du die Signatur der Funktion aendern? Wenn nein, dann ist wohl "die variable Parameterliste" mehr oder weniger die beste Alternative.



  • Brooks schrieb:

    Was ist eine variable Parameterliste?

    schau mal hier: http://www.cppreference.com/wiki/c/other/va_arg

    Brooks schrieb:

    Je nach Zahl füllt die Funktion einen char Array.

    die funktion setzt mehrere bits in einem bit-string. weil sie dafür die ganzen bit-positionen braucht, wäre ein array[48] zur übergabe wohl das richtige.
    🙂



  • schau mal hier: http://www.cppreference.com/wiki/c/other/va_arg

    so wie ich das verstanden hab, muss bei va_arg() ebenfalls die parameter explizit angegeben werden + anzhal der parameter:

    answer = sum( 4, 4, 3, 2, 1 ); //answer = 10 (4+3+2+1)
    

    Das würde den Funktionsaufruf nicht vereinfachen.
    Falls z.b. 45 Parameter übergeben werden sollen ->
    müsste ich trotzdem alle 45 parameter eintippen plus die Anzahl "45" dazu? Oder habe ich was übersehen?



  • Brooks schrieb:

    müsste ich trotzdem alle 45 parameter eintippen plus die Anzahl "45" dazu?

    ja, sowas lohnt sich nur, wenn du mal mehr und mal weniger parameter übergeben willst. so wie's aussieht, braucht deine funktion aber immer alle 48 shorts.
    🙂



  • @Brooks;

    was hindert dich daran einfach ":" als Parameter angeben
    und in der Funktion den Parameter abfragen ->

    merke letzten Parameter
    wenn nächster Parameter == ":"
    dann lese nächsten Parameter
    dann zähle von letzem Parameter zum zu letzt gelesenen Paramter duch.

    aber der geschilderten Situation entsprechend, muss es genügen, oder?



  • ja, sowas lohnt sich nur, wenn du mal mehr und mal weniger parameter übergeben willst. so wie's aussieht, braucht deine funktion aber immer alle 48 shorts.

    Ja das ist schon drin. Der Vorgänger hat einfach die variable Parameterzahl realisiert, indem er die Parameter im Funktionskopf initialisiert hat:

    my_func(short param0=0, short param1=0, ... etc )
    {
        //implementation, bla bla
    }
    

    @Pai Mai

    ja daran habe ich schon gedacht. Wollte aber vorher fragen,
    ob es bereits sollche Funktionen existieren.



  • Also, so ganz klar ist mir Dein Problem nicht, aber 48 Parameter sind schon viel 😕 .

    Wie sieht die Deklaration der Funktion aus? Hat sie tatsächlich (wie schon angenommen) 48 Parameter, die per Voreinstellung auf "0" gesetzt werden?

    Wenn ja, dann würde ich den ursprünglichen Entwickler nicht gleich mit dem Baseballschläger traktieren, sofern es sich um eine ältere "gewachsene" Applikation handelt. C++ erlaubt nun mal, noch einen Parameter anzuhängen und vorzubelegen. Es ist (leider) manchmal auch zwingende Praxis, das zu tun.

    Aber als Abhilfe gibt es eigentlich nur ein Mittel. Die Aufrufkonvention zu ändern, das ganze Projekt "durchzunudeln" und an allen Stellen, wo diese Funktion aufgerufen wird, anzupassen.
    Damit der Compiler das merkt, empfehle ich z.B. die Deklaration folgendermassen zu Ändern:

    my_48Param_function(unsigned short *pIn, int nCount)
    

    Dann wird dir der Compiler alle Stellen um die Ohren hauen, an denen die Funktion aufgerufen wird. Und dann gilt es, konzentriert alles zu ändern.

    Dann kannst Du innerhalb der ursprünglichen Implementierung mit relativ wenig Änderung alles gut in den Griff bekommen, bei den aufrufenden Funktionen wirst Du halt etwas mehr ändern müssen.

    Je nach dem, wie alt diese Funktion ist, kann es von einem gravierenden Designfehlers Deines Vorgängers bis zu "Wie kann ich das Teil mit möglichst wenig Änderung am Leben halten" (man steht ja in der Regel in der SW-Entwicklung immer unter Druck) alles sein. Also nicht gleich den Baseballschläger 🙂

    Guß, Gio



  • Habe grade diesen Thread gesehen und musste lange, lange lachen. 48 Parameter an eine Funktion übergeben 😃
    Ist das vielleicht so ein Gag von Software Architekten, so was ähnliches wie "Hol mal ne Holzelektrode" oder "Besorg mal ein Funkverlängerungskabel"
    😃
    Und jetzt "Schreib mal eine Funktion mit 48 Parametern" 😃



  • Gio schrieb:

    (man steht ja in der Regel in der SW-Entwicklung immer unter Druck)

    😃



  • @abc.w:
    Du kannst es Leuten, die Rat suchen, auch so versauen, dass sie sich nicht mehr trauen, irgendwo danach zu suchen!



  • Gio schrieb:

    Wenn ja, dann würde ich den ursprünglichen Entwickler nicht gleich mit dem Baseballschläger traktieren, sofern es sich um eine ältere "gewachsene" Applikation handelt. C++ erlaubt nun mal, noch einen Parameter anzuhängen und vorzubelegen. Es ist (leider) manchmal auch zwingende Praxis, das zu tun.

    Mal davon abgesehen dass ich den Entwickler auch im Falle von C++, unabhängig vom äußeren Druck, totschlagen würde: Es geht hier um C, da gibt es default-Parameter nicht.



  • Brooks schrieb:

    Der Vorgänger hat einfach die variable Parameterzahl realisiert, indem er die Parameter im Funktionskopf initialisiert hat:

    my_func(short param0=0, short param1=0, ... etc )
    {
        //implementation, bla bla
    }
    

    das wäre aber ein waschechter syntax-error. du kannst param0,param1 usw. im innern der funktion ändern, aber nicht im funktionskopf. selbst wenn es gehen würde, woher soll der compiler wissen, welche parameter du ändern willst, wenn du die funktion mit z.b. 5 parametern aufrufst?
    🙂



  • Hallo,

    woher soll der compiler wissen, welche parameter du ändern willst, wenn du die funktion mit z.b. 5 parametern aufrufst?

    die Parameter sind ja Zahlen. Die Reihenfolge spielt keine Rolle.
    Nur der Zahlenwert ist wichtig. So können es also my_func(1,0,7) oder
    my_func(7,1) gleiches Ergebnis liefern -> siehe Beitrag von gestern.

    Das mit dem Pointer wäre vermutlich die beste Lösung.
    Nur scheue ich mich davor zig Datein an zig Stellen zu ändern.

    Hab bei meiner Recherchein einem Ralaiskarte-Handbuch das gefunden:

    CLOSE (@14:16,71)
    //This command closes relays 14, 15, 16, and 71.
    

    und sowas würde ich hier auch brauchen. Damit ich nicht alles explizit eintippen muss. Wie wird sowas gemacht? geparst, variable Parameterliste?



  • und was ist mit

    struct param_list {
    int param1;
    ..
    int param48 }[]
    
    void func(const struct param_list *param)
    {
    ..
    }
    

    Hat den Vorteil, dass du den Stack nicht überfrachtest und damit die Funktion schneller aufgerufen wird.

    Gruß



  • sorry hätte erst lesen dann antworten sollen... letzten beitrag bitte ignorieren



  • Das mit dem Pointer wäre vermutlich die beste Lösung.
    Nur scheue ich mich davor zig Datein an zig Stellen zu ändern.

    Sehe ich persönlich aber als beste Lösung. Ansonsten bist Du dabei, einen Parser für die übergebenen Argumente zu implementieren. Und ob das schneller/besser ist, wage ich zu beweifeln.

    Und ausserdem, Du müsstest sowieso an "zig" Stellen im Programm Änderungen vornehmen, da sich die Aufrufkonvention der Funktion ändert.


Anmelden zum Antworten