If Schleife um Array Elemente zu vergleichen

Gast #6251024
Lesenswert?

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
Lesenswert?

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
}
#6251129
Lesenswert?

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
Lesenswert?

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 #6252008
Lesenswert?

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
Lesenswert?

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
Lesenswert?

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
Lesenswert?

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 #6252062
Lesenswert?

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
Lesenswert?

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
Lesenswert?

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
Lesenswert?

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
Lesenswert?

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
Lesenswert?

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
Lesenswert?

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
Lesenswert?

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
Lesenswert?

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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren