chars addieren



  • hmm.. komisch..

    also etwas konkreter:

    char CommandInChecksum[10];
    char Checksum[1];
    .
    .//CommandInChecksum bekommt Werte
    .
    Checksum[0] = CommandInChecksum[1] + CommandInChecksum[2];
    

    ... wird nicht compiliert:
    "'=': Linker Operand muss ein L_Wert sein"

    Auch wenn ich die Größe von Checksum erweiter, hilft das nix.
    Ist bestimmt ein Grundgedankenfehler drin, richtig? 😕



  • Ein Array für EIN Element? Ist das nicht ein wenig übertrieben? Hast du es mal mit einem einfachen 'char'-Wert versucht?

    PS: Aber eigentlich sollte das Array-Element ein lvalue sein - es sei denn natürlich, du hast da unterwegs noch ein anderes 'Checksum' angelegt.



  • Oh mann...
    Hier wird man echt schnell geholfen 😉
    Sau gut. Hatte echt noch aus anderen Versuchen ein checksum deklariert.
    Es funzt.
    Und zugegeben char[1] macht natürlich wenig Sinn. Auch ein Rest aus Verzweiflungstaten 😉
    Vielen Dank erstmal.



  • Hoffe mal, das wird trotzdem noch gelesen.. wollte nicht gleich einen neue Thread öffnen.

    Warum springt der Compiler nicht in die Funktion:

    int Endcommand = 9;
    int count;
    unsigned char CommandComplete[11];
    .
    . // alle Variablen werden schon irgendwo deklariert ;)
    .
    void CCom::OnMakeCommand(unsigned char CommandIn[10])
    {
    	for (count = 10; ((count = 0) || (CommandIn[Endcommand] != 0xFF)); count--)
    	{
    		Endcommand--;
    	}
    	for (count = 0; count <= Endcommand; count++)
    	{
    		CommandComplete[count] = CommandIn[count];
    	}
    
    	CommandComplete[Endcommand] = OnMakeChecksum(CommandIn); //von hier aus soll der Compiler eigentlich in die untere
    //Funktion springen.
    //Tut er aber nicht.... seltsamerweise hat checksum trotzdem plötzlich einen Wert,
    //aber einen falschen Wert.
    	ok = OnWriteCom(Endcommand + 1);
    	Endcommand = 9;
    }
    
    unsigned char CCom::OnMakeChecksum(unsigned char CommandInChecksum[10])
    {
    	switch(Endcommand)
    	{		
    		case 9:
    		{
    			CommandInChecksum[4] = (CommandInChecksum[4]^(0xFF)) + 0x01;
    			CommandInChecksum[5] = (CommandInChecksum[5]^(0xFF)) + 0x01;
    			CommandInChecksum[6] = (CommandInChecksum[6]^(0xFF)) + 0x01;
    			CommandInChecksum[7] = (CommandInChecksum[7]^(0xFF)) + 0x01;
    			CommandInChecksum[8] = (CommandInChecksum[8]^(0xFF)) + 0x01;
    
    			checksum = CommandInChecksum[4] + CommandInChecksum[5] 
                            + CommandInChecksum[6] + CommandInChecksum[7] + CommandInChecksum[8];
    			break;
    		}
    /*		case 8:
    			{
    			}
    		case 7:
    			{
    			}*/
    	}
    	return checksum;
    }
    

    Also compiliert wird der Kram.. und ja ich werde noch diese Checksummenbildung durch schleifen verkürzen / verschönern und so weiter....
    Aber wieso springt er nicht in die Funktion OnMakeChecksum?
    Wollte nicht noch mehr Code posten. Wenns aber zur Lösung beiträgt kann ich das natürlich noch nachholen.
    Danke.



  • Hast du das ganze mal durch den Debugger geschickt und dabei nachgesehen, wohin er tatsächlich springt?

    (btw, ich hoffe es stört dich nicht, daß bei dem Aufruf das übergebene Kommando (CommandIn) pulverisiert wird).



  • Also das komische ist, er springt in die Zeile:

    CommandComplete[Endcommand] = OnMakeChecksum(CommandIn);
    

    dann drücke ich F11 (für Einzelschritt) und er geht einfach eine Zeile weiter 😕 .

    Dass CommandIn pulverisiert 😃 wird stört mich zwar nicht, da ich es vorher auf
    CommandComplete rette, aber ich wüsste schon gerne warum das so ist und wie ich
    das verhindern könnte.
    Vielen Dank schonmal.

    Nachtrag:
    Während ich auf eine Antwort wartete, habe ich die Checksummen Funktion auf einen Zweizeiler verkürzt.
    Und jetzt plötzlich wie durch ein Wunder springt er in die Funktion und gibt auch die korrekte Checksumme... hmm.. muss ich das verstehen?



  • Mackie1980 schrieb:

    Dass CommandIn pulverisiert 😃 wird stört mich zwar nicht, da ich es vorher auf
    CommandComplete rette, aber ich wüsste schon gerne warum das so ist und wie ich
    das verhindern könnte.
    Vielen Dank schonmal.

    Die ganzen Zuweisungen CommandInChecksum[4] = (CommandInChecksum[4]^(0xFF)) + 0x01; schreiben in dem übergebenen Array. Um das zu verhindern, mußt du diese Zuweisungen weglassen und stattdessen die Berechnungen in die große Addition integrieren.

    Nachtrag:
    Während ich auf eine Antwort wartete, habe ich die Checksummen Funktion auf einen Zweizeiler verkürzt.
    Und jetzt plötzlich wie durch ein Wunder springt er in die Funktion und gibt auch die korrekte Checksumme... hmm.. muss ich das verstehen?

    Hmm, seltsam. Vielleicht war ja deine Funktion nicht ganz korrekt.

    *grübelt* was mir noch auffällt: ich glaube, in der ersten for-Schleife sollte es besser 'count==0' heißen.



  • Ok...
    Dann hing wohl alles mit meiner umständlichen Ausdrucksweise zusammen.
    Habe es jetzt auf das hier verkürzt:

    void CCom::OnMakeCommand(unsigned char CommandIn[10])
    {
    	for (count = 10; ((count == 0) || (CommandIn[Endcommand] != 0xFF)); count--)
    	{
    		Endcommand--;
    	}
    	for (count = 0; count <= Endcommand; count++)
    	{
    		CommandComplete[count] = CommandIn[count];
    	}
    
    	CommandComplete[Endcommand] = OnMakeChecksum(CommandIn);
    	ok = OnWriteCom(Endcommand + 1);
    	Endcommand = 9;
    }
    
    unsigned char CCom::OnMakeChecksum(unsigned char CommandInChecksum[10])
    {
    	checksum = 0x00;
    	for (count = 4; count < Endcommand; count++)
    	{
    		CommandInChecksum[count] = (CommandInChecksum[count]^(0xFF)) + 0x01;
    		checksum = checksum + CommandInChecksum[count];
    	}
    	return checksum;
    }
    

    Sieht ja gleich viel schicker aus und funzt besser 🙂
    Hoffe mal, Du meintest das count==1 aus der Abbruchbedingung!?

    So und jetzt meine letzt Frage (für heute 😉 ):
    Um ein char array (diesmal auch größer 1 😉 ) in ein anderes zu kopieren,
    muss ich da wirklich jedesmal ne Schleife bauen oder gibts da auch einen "echten"
    Befehl / Einzeiler für?

    Im voraus herzlichen Dank. Hast mir echt den Tag gerettet.



  • Einen Befehl gibt es nicht dafür, aber einige Funktionen: memcpy(), strcpy() (letzteres für nullterminierte Strings) aus der C Bibliothek oder std::copy() aus der C++ STL.

    PS: Wie gesagt, würde ich die Eingabedaten nur pulverisieren, wenn es gar nicht anders geht - und in deinem Fall ist es unnötig:

    //ungünstig:
    for (count = 4; count < Endcommand; count++)
    {
      //überschreibt das eingegebene Array
      CommandInChecksum[count] = (CommandInChecksum[count]^(0xFF)) + 0x01;
      checksum = checksum + CommandInChecksum[count];
    }
    
    //bessere Lösung:
    for(count=4;count<EndCommand;++count)
      checksum += (CommandInChecksum[count]^0xFF) + 1;
    

    PPS: Ja, ich meinte den Vergleich in der Abbruchbedingung 😉



  • Krass...
    Tja, da merkt man doch das fehlende Studium 😉 oder besser gesagt die andere Fachrichtung.
    Vielen Dank.


Anmelden zum Antworten