If Schleife um Array Elemente zu vergleichen

Gast #6251024
Servus Leute,

und zwar möchte ich mit einer Laufvariable den aktuellen Wert eines 
Arrays mit dem nächsten vergleichen. Bei den Werten handelt es sich um 
einen binären Code. Mit einer If-Schleife vergleiche ich erfolgreich die 
Werte bis zum Ende des Arrays. Am Ende angekommen möchte ich aber den 
letzten Wert mit dem ersten Wert des Arrays vergleichen. Wie kann ich 
dafür meine Bedingung anpassen?
1
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
2
{
3
  if(code[i] == code[i+1])
4
  {
5
    GPIOA->ODR ^= (1<<8);
6
  }
7
  else
8
  {
9
    GPIOA->BSRR = (0<<24);
10
  }
11
  i++;
12
    
13
  if(i == 9)
14
  {
15
    i=0;
16
  }    
17
}
Mein Binärcode besteht aus 10 Werten. Sobald ich einmal durchgelaufen 
bin wird Wert [9] aber nicht mit Wert [0] verglichen sondern [0] mit 
[1]. Hat jemand einen Goldenen Tipp?
Gast #6251096
Dirk B. schrieb:
> Du kannst auch ein j einführen

Zum Beispiel so:
1
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
2
{
3
  // Calculate index of the next element
4
  int j=i+1;
5
  if(j == 9)
6
  {
7
    j=0;
8
  }
9

10
  if(code[i] == code[j])
11
  {
12
    GPIOA->ODR ^= (1<<8);
13
  }
14
  else
15
  {
16
    GPIOA->BSRR = (0<<24);
17
  }
18

19
  // prepare for next call.
20
  i=j;
21
}
Gast #6251108
Versuchs doch mal mit Modulo 10.
also:
   if(code[i] == code[(i+1)%10])
und dann noch die Zeile
   if(i == 9)
in :
   if(i > 9)
ändern, damit er auch bis zum Index 9 geht, dann sollte es 
funktionieren.
#6251129
smerti schrieb:
> Mein Binärcode besteht aus 10 Werten. Sobald ich einmal durchgelaufen
> bin wird Wert [9] aber nicht mit Wert [0] verglichen sondern [0] mit
> [1].

Das kann man mit dem Modulo Operator erreichen. Ein Code-Beispiel für 
die Ausgabe am Konsolenfenster wäre etwa das hier:
1
#include <stdio.h>
2

3
int main()
4
{
5
    unsigned int i;
6
    
7
    for (i=0; i<10; i++)
8
    {
9
        printf("%2d | %2d\n", i%10, (i+1)%10);
10
    }
11
    
12
    return 0;
13
}

Ausgabe:
1
 0 |  1
2
 1 |  2
3
 2 |  3
4
 3 |  4
5
 4 |  5
6
 5 |  6
7
 6 |  7
8
 7 |  8
9
 8 |  9
10
 9 |  0
#6251151
Dirk B. schrieb:
> Du kannst auch ein j einführen:
> j = i+1;
> j = (j>=max) ? 0: j

Da von 0 bis 9 gezählt wird:
1
j = (i < 9) ? i+1 : 0;
Und am Ende kann man dann einfach ein
1
i = j;
machen, um weiter zu zählen.

smerti schrieb:
> leo schrieb:
>> Und das ist falsch.
>
> Wie kommst du da drauf? Funktioniert nämlich

Ob falsch oder nicht - es ist jedenfalls recht unsinnig, 0 um 24 Bit 
nach links zu schieben. Das Ergebnis bleibt dabei 0.
Dein
1
GPIOA->BSRR = (0<<24);
ist also genau das gleiche wie
1
GPIOA->BSRR = 0;
Gast #6251994
leo schrieb:
> Du toggelst ODR mit dem xor-Befehl davor und nicht mit diesem NOP. Lies
> das Handbuch, lerne C.

Woher willst du denn wissen das ich das Bit mit diesem NOP Befehl 
Toggeln will? Soll nämlich schon ein NOP sein.
Gast #6252008
smerti schrieb:
> Woher willst du denn wissen das ich das Bit mit diesem NOP Befehl
> Toggeln will? Soll nämlich schon ein NOP sein.

Optimiert der Compiler das nicht komplett weg, weil der Befehl 
letztendlich nichts* bewirkt?

*) Ausser Zeit zu verbrauchen, aber das genau das will der Compiler ja 
auch minimieren.
Gast #6252018
Stefan ⛄ F. schrieb:
> Optimiert der Compiler das nicht komplett weg, weil der Befehl
> letztendlich nichts* bewirkt?
>
> *) Ausser Zeit zu verbrauchen, aber das genau das will der Compiler ja
> auch minimieren.

Funktioniert auch ohne, hatte die Operation tatsächlich drin um Zeit zu 
verbrauchen damit die Ausgangsfrequenz stimmt.
#6252026
smerti schrieb:
> Soll nämlich schon ein NOP sein.

Das ist allerdings eine recht kreative Art, ein NOP zu schreiben. Wer 
den Code liest, wird sich zuerst fragen, warum da eine 0 geschoben wird, 
und dann, warum ausgerechnet um 24 Bit.

Stefan ⛄ F. schrieb:
> Optimiert der Compiler das nicht komplett weg, weil der Befehl
> letztendlich nichts* bewirkt?

Die Schiebe-Operation wird mit Sicherheit wegoptimiert. Da wird einfach 
nur 0 in das Register geschrieben. Der Schreibzugriff selbst wird aber 
wohl eher nicht wegoptimiert.
Gast #6252033
A. S. schrieb:
> aber die Logik ist vermutlich eine andere: Da BSRR 24 Bit ist,
> möchte er sicher sein, dass auch wirklich alle 24 Bit 0 sind, und nicht
> nur das Ergebnis ;-)

Möglicherweise wollte er auch Bit 25 (Zählweise Bit 1 ist das 
niederwertigste) löschen und die anderen beibehalten wie sie waren, was 
er mit der Anweisung natürlich verkackt.
Gast #6252038
Rolf M. schrieb:
> warum ausgerechnet um 24 Bit

Weil es das korrespondierende Bit für mein ODR Bit ist und mit einer 0 
einfach keine Operation durchgeführt wird. Das habe ich in dem moment so 
gefunden und benötigt. Aber gut anscheinend für die Katz
Angehängte Dateien:
Gast #6252062
smerti schrieb:
> und mit einer 0 einfach keine Operation durchgeführt wird.

Was meinst immer Du damit meinst, ist vermutlich ein Missverständnis der 
und sollte (für Dich) aufgeklärt werden. Irgendwann kommt der Zeitpunkt 
als Anfänger, wo man programmierzeilen nicht probieren sondern 
formulieren und nachvollziehen sollte.

Alles probierte haut der Compiler dir beim optimieren (nur ein 
Federstrich) um die Ohren.

Überlege, was Du wolltest und was Du programmiert hast. Und wenn es was 
anderes tat als erwartet, dann lies, frag oder forsche nach.
Gast #6252439
smerti schrieb:
> Hat jemand einen Goldenen Tipp?
Falls du noch Speicherplatz für ein einziges weiteres Array-Element 
erübrigen kannst, könntest du vor der Vergleichsorgie den ersten Wert 
noch einmal ganz nach hinten kopieren. Dann löst sich dein Problem quasi 
in Luft auf.
Gast #6252775
Wolfgang schrieb:
> Falls du noch Speicherplatz für ein einziges weiteres Array-Element
> erübrigen kannst, könntest du vor der Vergleichsorgie den ersten Wert
> noch einmal ganz nach hinten kopieren. Dann löst sich dein Problem quasi
> in Luft auf.

Das ist oft der Pragmatische Ansatz, der das alles viel einfacher und 
lesbarer macht.

Ist halt nur selten, dass man die Daten(Strukturen) an der Stelle "in 
der Hand" hat.
Gast #6252797
A. S. schrieb:
> Das ist oft der Pragmatische Ansatz, der das alles viel einfacher und
> lesbarer macht.

Das sehe ich anders. Denn dazu musst du zwischen dem letzten und 
vorherigen Elementen unterscheiden.

Dennoch musst du trotzdem mindestens eine Index variable bei jedem 
Durchlauf erhören und am Ende auf 0 zurück setzen.
Gast #6254206
Stefan ⛄ F. schrieb:
> Das sehe ich anders. Denn dazu musst du zwischen dem letzten und
> vorherigen Elementen unterscheiden.
>
> Dennoch musst du trotzdem mindestens eine Index variable bei jedem
> Durchlauf erhören und am Ende auf 0 zurück setzen.

Äh, wieso?

Wenn Du das Element0 nochmal hinter das letzte Element setzt, dann läuft 
Deine Schleife ohne Verrenkung bis zum Ende und ist fertig.
extern Code
1
extern int code[10+1];
2

3
   code[10]=code[0];
4

5
   for(int i=0; i<10; i++) {foo(code[i], code[i+1]);}

kein Modulo, keine if, kein zweiter index, ...
Gast #6254220
Stefan ⛄ F. schrieb:
> Dennoch musst du trotzdem mindestens eine Index variable bei jedem
> Durchlauf erhören und am Ende auf 0 zurück setzen.

Falscher Ansatz.
Du setzt beim Start die Indexvariable i auf des kopierte Element.
In der Schleife vergleichst immer y[i] mit y[i-1] und dekrementierst i.
Wenn i==0, hast du fertig.
Gast #6254260
A. S. schrieb:
> dann läuft Deine Schleife ohne Verrenkung bis zum Ende und ist fertig.

Bei jedem Interrupt soll nach nächste Element aus dem Array verarbeitet 
werden. Wenn das letzte Element erreicht wurde, beginnt die Verarbeitung 
wieder von vorne.  Also braucht man immer noch einen entsprechenden 
Test, bei dessen Erfüllung i auf 0 gesetzt wird.
Gast #6254345
smerti schrieb:
> if(code[i] == code[i+1])

smerti schrieb:
> Mein Binärcode besteht aus 10 Werten. Sobald ich einmal durchgelaufen
> bin wird Wert [9] aber nicht mit Wert [0] verglichen sondern [0] mit
> [1].

Bei der Bedingung ist der letzte Vergleich gar nicht nötig. (wenn i von 
1 bis 10 läuft)

Wenn benachbarte Elemente gleich sind, dann sind auch das letze und das 
erste Element gleich.

a==b und b==c  ---> a==c

Bist du dir sicher, dass du es so vergleichen willst?
#6254430
zitter_ned_aso schrieb:
> Wenn benachbarte Elemente gleich sind, dann sind auch das letze und das
> erste Element gleich.
>
> a==b und b==c  ---> a==c
>
> Bist du dir sicher, dass du es so vergleichen willst?

Wenn genau zwei Elemente gleich sind, bedeutet das nicht automatisch, 
dass alle Elemente gleich sind. Bei jedem Aufruf der Funktion werden ja 
nur zwei Elemente miteinander verglichen, nicht mehr. Was zwischen den 
Aufrufen damit passiert, weiß man nicht.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 6 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.