Forum: Mikrocontroller und Digitale Elektronik Index vom Maxwert eines Array ermitteln und umsortieren


von Peter C. (Gast)


Lesenswert?

Hallo zusammen,
ich habe einen ATMega mit dem ich am Int2 einige Pulsfolgen vermesse und 
in einem Array (8 Werte) speichere. Danach weiderholt sich die Pulsfolge 
wieder. Da die externe Pulsfolge je nach Zuschaltung der Messung immer 
in anderer Folge im Array gespeichert wird, möchte ich anhand des 
Maximalwertes das Array neu sortieren da ich nur einen bestimmten Wert 
aus dem Array weiterverarbeiten will.

Nach Umstieg auf C, also noch Anfänger, bin ich nun dabei mein altes 
Bascomprogram auf C umzustellen und stolpere nun über diese Funktion.

Die Max Funktion ist eine Bascomfunktion. Mit der wird der Maximalwert 
in Idx zurückgegeben (oder der Maxzahlenwert in M1). Die Reihenfolge im 
Array bleibt gleich es soll nur nach Index umsortiert werden.

Ein Beispiel
vorher:
Index  1   2   3   4   5   6   7   8
Wert  200 400 300 700 600 500 800 100

nachher:
Index  1   2   3   4   5   6   7   8
Wert  800 100 200 400 300 700 600 500

Gibt es soetwas in C

    Max(tmess(1) , M1 , Idx)
          Y = Idx
            For X = 1 To 8
               If Y = 9 Then Y = 1
                 Ttemp(x) = Tmess(y)
            Incr Y
 Next

Hat einer ein Tipp ????????

Gruß
Peter

von Noname (Gast)


Lesenswert?

Offen gesagt verstehe ich nicht was Du eigentlich willst.

Wenn Du nur den maximalen verarbeiten willst, dann reicht es doch, ihn 
zu ermitteln. Warum umsortieren?

Wenn das gelten soll
>Die Reihenfolge im Array bleibt gleich es soll nur nach Index umsortiert >werden.

wie passt das denn zu

>Ein Beispiel
>vorher:
>Index  1   2   3   4   5   6   7   8
>Wert  200 400 300 700 600 500 800 100

>nachher:
>Index  1   2   3   4   5   6   7   8
>Wert  800 100 200 400 300 700 600 500

denn da sind ja nicht die Indizes sondern doch die Werte umsortiert?

Und nach welchem Kriterium sollen denn die Daten in dem Beispiel soriert 
worden sein?

Ein ziemliches Kuddelmuddel.

von H.Joachim S. (crazyhorse)


Lesenswert?

Hm, verstehe dein Beispiel auch nicht.
Sieht so aus, als ob das array solange durchgeschoben wird, bis der 
MAX-Wert an erster Stelle steht. Was hast du davon?
Entweder will man den Max-Wert wissen oder man will die Daten sortieren.
Für deinen Fall (so wie ich es verstanden habe) reicht doch, das Maximum 
zu finden und aus dessen Index den Offset zu finden?

von MagIO (Gast)


Lesenswert?

Also 1.
Dein Maximum kannst Du doch gleich beim Messen schon ermitteln. Bevor Du 
eine Messreihe startest, setzt Du eine Variable (z.B. maxVal) auf 0.
Messen & im Array speichern, ist der Wert größer als maxVal setzt Du 
maxVal auf den aktuellen Wert und merkst Dir noch den index.

Und 2.
Warum umsortieren? Du sortierst ja nicht wirklich nach größe, sondern Du 
verschiebst die Messreihe, die Sortierung (also Reihenfolge) bleibt die 
gleiche. Statt das komplette Array zu verschieben kannst Du auch alle 
folgenden Zugriffe einfach mit einem Offset versehen und mit dem modulo 
operator dafür sorgen, dass am ende des Arrays wieder von vorne 
angefangen wird. Das geht im übrigen weitaus schneller, wenn dein Array 
8, 16, 32 .... Elemente hat, da Du dann die modulo-operation einfach 
durch ein bitweises UND ersetzen kannst.

loop über das ganze Array beginnend von der Stelle
for(i=0;i<ARRAY_LENGTH;i++)
  doWhatever( messwert[ (idxMax + i) % ARRAY_LENGTH ] )

(hoffe Du kanns das in basic übersetzen - ich wüsste aber jetzt auch 
nicht wie der modulo-operator in basic aussieht - bin mir nicht mal 
sicher ob % richtig ist ;o)

von Peter C. (Gast)


Lesenswert?

Hallo,
ich versuche es nochmal besser zuerklären.
Eine wiederkehrende Puls-Pausenfolge beinhaltet einen hineincodierten 
Flüssigkeitsstand und eine Flüssigkeitstemp (4 x Puls und 4 x Pause) der 
mit Hilfe des Int2 des Atmega gemessen wird. Die Messdaten werden der 
Reihe nach wie sie gemessen werden in dem Array gespeichert. Aufgrund 
der Zuschaltung, des Einsatzes der Messschaltung landet der längste Puls 
(Startpuls) aber nicht immer im Index 1 - Start-Zufallsprinzip. Auch die 
Länge des längsten Pulses ändert sich im Verlauf mit steigende 
Flüssiglkeitstemp somit kann ich da keine feste Basis ansetzen und muß 
immer vom längsten Puls/größten Wert ausgehen und aus dem 7.Index den 
Wert übernehmen und das nach jedem Messzyklus. Also im Zweifel nach 
jedem Messzyklus immer neu durchschieben bis der längste/größte Wert an 
Index 1 angekommen ist.
Der entsprechende Wert ist nach meinem Vorgehen dann immer im Index 7 
und daraus errechne ich dann die Flüssigkeitstemperatur. Ich glaube 
durchschieben ist der richtige Audruck. Sonst ist mir der längste 
Puls/größter Wert egal.
Sicher ist die Lösung für einen Profi anders zulösen...denke 
ich....."ich" konnte das damals mit Bascom nicht anders hinbekommen.

Jetzt möchte ich diese Funktionalität aber in mein C Programm übernehmen 
und bin ich für jeden Vorschlag oder jedes Beispiel dankbar, ich möchte 
es nur auch begreifen können.
Ich möchte also nichts in Basic übersetzen sondern es in C lösen. Das 
Beispiel ist ja Basic und funktioniert auch, nur in C bekomme ich es so 
nicht übersetzt - bin halt C Anfänger.

Ich hoffe ich konnte mich verständlicher ausdrücken.

Gruß
Peter

von H.Joachim S. (crazyhorse)


Lesenswert?

Ich gehe jetzt mal von Index 0..7 aus, 1..8 ist blöd :-)
-suche das Maximum -> dessen Index ist z.b. bei dir 6 (orignal 7)
-addiere zu diesem Index den Abstand zu dem Wert, den du suchst (bei dir 
6),
Ergebnis 12
-ist der berechnete Index grösser als dein Array, ziehe die Array-Grösse 
(8) ab
-jetzt hast du den richtigen Index: 4

von Peter C. (Gast)


Lesenswert?

Hallo,
ja Bascom kennt nur 1-8 und in C ist es 0-7 - genau.
Also deiner Ausführung kann ich so nicht folgen. Vielleicht ist es schon 
spät oder ich schnall es nur nicht.

Also die Bascom Funktion/Prozedur macht folgendes.

 Max(tmess(1) , M1 , Idx)
 //ermittle aus dem Array Tmess ab index 1 den Index des größten Wertes.
 // der Index des größten Wertes wird an Y übergeben. M1 wäre der größte 
Werte, mich interesiert ja so dann nur der Index zum durchschieben
         Y = Idx


            For X = 1 To 8
               If Y = 9 Then Y = 1
                 Ttemp(x) = Tmess(y)
            Incr Y
            Next

// in der Schleife wird jetzt die neue Abfolge X1 - X8 mit den Werten 
aus Index Y7, Y8 , Y1 - Y6  gefüllt, quasi bis zum Index 1 
durchgeschoben.

Ich habe eine Demoschaltung auf dem Tisch und schreibe morgen mal die 
Werte mit Index raus. Vielleicht komme ich dann dahinter.
Achja....die Werte sind immer die Zeiten zwischen den high/low 
...low/high usw..Flankenwechsel.
So das sich Werte im Array befinden die mit Zeiten vergleichbar sind.
Index   Wert
0       3500
1       3500
2       13700
3       1000
4       1500
5       1550
6       16000
7       1000

So ist der längste/größte Wert in Index 6 und gebraucht wird Index 4 und 
nach durchschieben ist der größte Wert in Index 0 und der der gebraucht 
wird in Index 6
Wenn ich natürlich ohne die Schieberei direkt den Index des 
längsten/größten Werts ermittle und nur "einfach" + Abstand (+7) rechne 
sollte es gehen.....meinst du das so. ???
Dennnoch muß ich erst den Index des größten Wertes ermitteln.
Also Wert mit Wert vergleichen den größeren übernehmen und kleinere 
verwerfen bis man bis 7 bzw bei Bascom 8 durchgezählt hat.

Oder geht das einfacher ??????

ja ist doch schon spät.........ich komm aber langsam dahinter, ahhhhh 
das hätte mit Basic auch funktionieren können.

Peter

von Karl H. (kbuchegg)


Lesenswert?

Peter C. schrieb:

> Dennnoch muß ich erst den Index des größten Wertes ermitteln.

Na ja gut.
Das ist ja nicht das grosse Problem, sich dafür eine Funktion zu 
schreiben.

1
int MaxIndex( int Werte, int AnzahlWerte )
2
{
3
  int max = Werte[0];
4
  int maxIndex = 0;
5
  int i;
6
7
  for( i = 1; i < AnzahlWerte; i++ ) {
8
    if( Werte[i] > max ) {
9
      max = Werte[i];
10
      maxIndex = i;
11
    }
12
  }
13
14
  return maxIndex;
15
}


Aber ganz ehrlich. Ich hab (und ich hoffe ich bin da nicht alleine) auch 
nach deiner letzten Erklärung nicht geschnallt, was du eigentlich machen 
willst und warum. Erklär das doch mal ohne das du auf BASCOM 
zurückgreifen musst.

von Karl H. (kbuchegg)


Lesenswert?

Ach jetzt hab ich dich.

Du willst das Array solange rumrotieren, bis der grösste Wert ganz vorne 
steht.
Kann man machen, muss man aber nicht machen. Den größten Wert suchen, 
dort ist der Anfang. Und dann gehts wie bei der Uhr: Kommt man zum 
letzten Wert im Array, dann gehts einfach wieder von vorne los. Ist 
einfach nur ein bischen Indexrechnerei beim Zugriff.

von MagIO (Gast)


Lesenswert?

Also nochmal ein Versuch ... eine Funktion wie MaxIndex ist sozusagen 
eine Nachverarbeitung der Messwerte!
Aber so wie ich Dich verstehe, erfasst Du doch immer 8 Werte und machst 
dann die Verarbeitung. Somit hast Du irgendwo code, der das Erfassen der 
nächsten 8 Werte startet. Mit wenigen Instruktionen kann man das 
Ermitteln des max-Wertes und seines index doch direkt in dem code 
machen, der die Messwerte ermittelt.

Also in Pseudo-code:
maxVal = 0;
starteMesswerterfassung;
...

Messwerterfassung:
wiederhole 8 mal
  speichere Messwert in array
  wenn Messwert > maxVal, dann maxVal = Messwert, maxIdx = 
aktuellerIndex

Damit hast Du nach dem Messen den Index direkt zur Hand.

Wenn dich jetzt ein Messwert relativ zum Index interessiert, dann kannst 
Du darauf zugreifen, indem Du mit dem Modulo arbeitest:

valIdx = ( maxIdx - 2 ) % ARRAY_LENGTH

damit brauchst Du also auch nicht das Array umkopieren.

Da Du von Startpuls sprichst wundert es mich ein wenig, dass Du in 
Deinem Beispiel dann am Wert von LangerPulsIndex - 2 interessiert bist. 
Mit dieser Messmethode scheint es mir so, dass Du manchmal den 
aktuellsten Messwert bekommst (langer Puls am Anfang der Messreihe) und 
manchmal einen gerade veralteten (langer Puls am Ende der Messreihe).

Gibt es zu dem Teil, das Dir die Pulse liefert irgend eine Doku?

von Peter C. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo
ein Flüssigkeitssensor gibt über ein Datenstrom den Flüssigkeitsstand 
und die Temperatur der Flüssigkeit aus. Dieser Datenstrom wird als 
Rechtecksignal mit entsprechender Amplitude ausgesendet. Die komplette 
Sequenz hat 4 Pulse und 4 Pausen (im angehängten Bild ist nur die Hälfte 
drauf - lange Pause ist auch unterschiedlich). Der längste gemessene 
Wert bildet quasi den Start. Der Wert der dann nach dem Start als 
7.(Array 0-7=Index 6) gemessen wird, beinhaltet die Temperatur bzw den 
Zeitwert den ich weiter verarbeite. Mich interessiert auch nur dieser 
Wert. Die Brücke über den größten Wert und dessen Index sowie das 
durchschieben ist für mich nur die Eselsbrücke um an den 6. Wert (Array 
0-7) zugelangen.
Die Rechnerei mit dem Index erscheint mir auch einfacher....als Änfänger 
mit C hangelt mach sich so dahin und der Profi hat den Durchblick und 
weiß deutlich schneller was da geht. Ich glaube jetzt habe ich 99 
Prozent der Eingangsvorraussetzungen beschrieben.
- längster Wert = Start
- benötigter Wert ist dann im 6. folgenden Messwert

Das finde ich schon als Anfänger so toll an C

Gruß
Peter

von Karl H. (kbuchegg)


Lesenswert?

Peter C. schrieb:

> und die Temperatur der Flüssigkeit aus. Dieser Datenstrom wird als
> Rechtecksignal mit entsprechender Amplitude ausgesendet. Die komplette
> Sequenz hat 4 Pulse und 4 Pausen (im angehängten Bild ist nur die Hälfte
> drauf - lange Pause ist auch unterschiedlich). Der längste gemessene
> Wert bildet quasi den Start.

Dieser längste Wert wird ja auch eine gewisse Mindestlänge haben, oder 
nicht?

Das würde ich so machen, dass ich bei auftreten eines entsprechend 
langen Pulses schon beim Abspeichern der Werte, den Zähler der regelt wo 
im Array die nächsten Pulse abgelegt werden einfach auf 0 zurücksetze. 
Damit kommt dann das restliche Telegramm automatisch richtig ins Array, 
beginnend bei 0. Und damit ist dein 'Problem' zum Nicht-Problem 
geworden, weil es ganz einfach gar nicht mehr auftritt. Nach dem ersten 
Telegram synchronisiert sich der ganze Mechanismus ganz von alleine und 
ohne sonstiges Zutun.

Ganz ähnlich, wie es auch RC-Empfänger machen, die die lange Pause nach 
den Einzelpulsen für die Servos dazu benutzen, einfach den internen 
Zähler zurückzusetzen.

> Das finde ich schon als Anfänger so toll an C

Hat mit C eigentlich nichts zu tun, sondern damit ob man erst mal ein 
wenig über mögliche Lösungsstrategien und deren Vor-/Nachteile sinniert, 
ehe man sich an den Editor setzt.

von Peter C. (Gast)


Lesenswert?

Hallo MagIO
eine Doku gibt es nicht, wird zumindest von dem Hersteller nicht 
herausgegeben. Einsatz im KFZ nur so für die Richtung. Der lange/längste 
Puls ist eine Orientierung für mich und von dort an finde ich dann 
meinen Wert heraus. der längste Wert ist eine Pause und so für mich ohne 
Inhalt, nur Pause.
Eine Sequenz wird immer aus diesen 8 Werten gebildet. Stock mal die 
Weiterverarbeitung ist das ja nicht schlim da in den dann folgenden 8 
Werten immer wieder die längste Stelle dabei ist und so auch wieder der 
Tempwert ermittelbar entweder nach durchschieben oder eben nach 
Indexrechnen.

Gruß
Peter

von Peter C. (Gast)


Lesenswert?

Hallo Karl Heinz,
leider verändert sich auch der längste Puls/Pause in der Zeit. Im Grunde 
gibt es 2 lange Pausen.  In dem Beispiel ist jetzt die längste Pause 
250ms und die 2. längste Pause rund 200ms. Steigt die Temperatur z.B. 
von 30 °C auf 70°C dann sieht es schon anders aus, dann ist die längste 
Pause schon rund 320ms und die 2. längste ist rund 260ms.

>Hat mit C eigentlich nichts zu tun, sondern damit ob man erst mal ein
>wenig über mögliche Lösungsstrategien und deren Vor-/Nachteile sinniert,
>ehe man sich an den Editor setzt.

jeep, zum Zeitpunkt der Überlegungen (vor 14 Monaten) habe ich ganz 
schön überlegt und bin damals mit Bascom auf genau die eingangs 
beschrieben Lösung gekommen.

Da die Messwertaufnahme in der ISR geschieht möchte ich da so einfach 
nichts weiter machen - wäre das den aus deiner Sicht falsch ????. 
Deshalb auch das durchschieben/sortieren in der Main.

Gruß
Peter

von Karl H. (kbuchegg)


Lesenswert?

Peter C. schrieb:
> Hallo Karl Heinz,
> leider verändert sich auch der längste Puls/Pause in der Zeit. Im Grunde
> gibt es 2 lange Pausen.  In dem Beispiel ist jetzt die längste Pause
> 250ms und die 2. längste Pause rund 200ms. Steigt die Temperatur z.B.
> von 30 °C auf 70°C dann sieht es schon anders aus, dann ist die längste
> Pause schon rund 320ms und die 2. längste ist rund 260ms.

Humpf.
Was n' das für ein Sensor?
Wo steckt denn da jetzt eigentlich die Information drinnen?

von MagIO (Gast)


Lesenswert?

Vielleicht solltest Du das Signal mal etwas länger mitschneiden. Ich 
würde ja mal eher vermuten, daß einer der beiden langen Pulse den 
Füllstand und der andere der beiden Pulse die Temperatur angibt.

Der eine Puls davor ist sozusagen das Start-Bit und gibt über seine 
Länge an, welcher Wert denn als nächstes kommt - Füllstand oder 
Temperatur.

Aber dazu müsste man mal ein paar mehr Messungen zum Vergleich haben.

von Peter C. (Gast)


Lesenswert?

Okay,
ich lüfte die Sensorfrage, es ist ein Ölstand- und Temperaturgeber aus 
dem VAG Bereich. Ich benutze extra nicht das A..o Wort weil ich hier 
keine unnötige Diskussion möchte die eine weitere Hilfe verhindert - 
somit hoffe ich das die Diskussion auch ausbleibt.
Die Information steckt in den auf Masse gezogenen Zeiten - definitiv da 
ich schon einen Simulator dafür gebaut habe um in einem A..o ein 
Kombiinstrument zubetreiben in dem es den Sensor nicht gab.
So entspricht z.B. der Öltemp von 60°C einem Zeitwert von 26,3ms oder 
100°C sind dann schon 32,5ms sowie bei 170°C sind es dann schon 44,5ms. 
An den richtigen Wert komme ich eben nur wenn ich vom längste Wert als 
Startparameter weiterzähle.


Gruß
Peter

von Karl H. (kbuchegg)


Lesenswert?

Peter C. schrieb:

> An den richtigen Wert komme ich eben nur wenn ich vom längste Wert als
> Startparameter weiterzähle.

Na ok. Wenn die Pausenzeiten sich so verhalten, dann ist das dann eben 
so. Dann eben hinten nach den größten suchen und von dort 'im Kreis' 6 
Plätze weiterzählen. Ist ja nun auch nicht gerade Raketentechnik und 
auch nicht zeitkritisch.
1
uint8_t IndexOf( uint8_t BaseIndex, uint8_t Offset, uint8_t ArraySize )
2
{
3
  uint8_t result = BaseIndex + Offset;
4
  if( result > ArraySize - 1 )
5
    result = result - ArraySize - 1;
6
7
  return result;
8
}

und dann eben
1
   ....
2
   Index = MaxIndex( Values, 8 );
3
   TempValue = Values[ IndexOf( Index, 6, 8 ) ];
4
5
   ....

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Suche ich in einem Array den Maximalwert werde ich qsort() an, im
ersten Element des Arrays steht dann entweder das Minimum resp. das
Maximum (je nach Vergleich).
1
int  werte[] = { 1, 2, 3 };
2
3
qsort( &werte, 3, sizeof( int), cmp);
4
...
5
6
  int cmp(
7
  int *a,
8
  int *b
9
{
10
  if ( *a == *b)
11
     return 0;
12
  else
13
     return *a < *b ? 0 : 1;
14
}

von Karl H. (kbuchegg)


Lesenswert?

Joachim Drechsel schrieb:
> Suche ich in einem Array den Maximalwert werde ich qsort() an,

das lohnt aber bei 8 Array Elementen nicht.
Da betreibt qsort mehr Overhead durch den Callback, als es Zeit 
gegenüber einer simplen Such-Schleife rausholt.

Und ausserdem darf er sein Array nicht verändern.

von MagIO (Gast)


Lesenswert?

Und der ganz langen Puls wechselt sich immer mit dem nich ganz so langen 
Puls ab?

Ok ... was ich dann machen würde:
1. Array vergrößern auf 16
2. ISR continuierlich laufen lassen
3. ISR schreibt die Messwerte in einen Ringbuffer (einfach mal in 
wikipedia eingeben) geht ganz einfach indem die index-variable um eins 
erhöht und anschließend mit "& 15" (bitweises UND) wieder auf 0 gesetzt 
wird, falls der aktuelle Wert dann 16 gewesen wäre.
4. wird ein langer Puls erkannt, dann wird geschaut, ob er länger ist 
als der vorherige
4a. wenn ja, dann index merken und pulszeit merken
4b. wenn nein, dann nur pulszeit merken

Warum:
1., 2. & 3. so kann die ISR die Werte ständig schreiben ohne, daß sie 
dem Hauptprogramm in die quere kommt. ISR schreibt immer vorne im 
Ringbuffer, während das Hauptprogramm hinten liest. Der Buffer ist groß 
genug um 2 Zyklen aufzunehmen.

4. das sind nicht so viele Instruktionen, die dafür benötigt werden. 
Dafür kann das Hauptprogramm jederzeit einen aktuellen Wert aus dem 
Buffer abgreifen.

Wie das Hauptprogramm an den aktuellen Wert kommt wurde ja auch oben 
schon erwähnt. (maxIndex - 2) & 15

von Peter C. (Gast)


Lesenswert?

Hallo
und danke für die Tipps, ich werde den Lösungsansatz von Karl Heinz für 
mich durchschnorchelen und sehen ob ichs in den Kopf bekomme.

Gruß
Peter

von Udo S. (urschmitt)


Lesenswert?

Karl Heinz Buchegger schrieb:
> result = result - ArraySize - 1;

Karl Heinz, bist du dir sicher daß das -1 stimmt?
Wenn ich ein Arry der Größe 8 habe, im Element mit Offset 5 (die 6. 
Speicherzelle) das Maximum habe und mein gesuchter Wert +5 hinter dem 
Maximum steht dann ist der Wert im Offset 2.
Das wäre aber 5 + 5 - 8

Oder läuft bei deiner Funktion der "BaseIndex" oder der "Offset" von 1 
los und nicht von 0?

von Karl H. (kbuchegg)


Lesenswert?

Udo Schmitt schrieb:
> Karl Heinz Buchegger schrieb:
>> result = result - ArraySize - 1;
>
> Karl Heinz, bist du dir sicher daß das -1 stimmt?

Nein.
Du hast recht. Copy & Paste Fehler.
Ohne -1

von MagIO (Gast)


Lesenswert?

Das wäre mit

uint8_t IndexOf( uint8_t BaseIndex, uint8_t Offset, uint8_t ArraySize )
{
  uint8_t result = BaseIndex + Offset;
  if( result >= ArraySize )
    result = result - ArraySize ;

  return result;
}

nicht passiert ;o)

von Peter C. (Gast)


Lesenswert?

Hallo Karl Heinz,
kannst du mir kurz erklären was in den einzelnen Zeile läuft ich kriege 
es nicht in den Kopf - ich gehe noch nicht so lange mit C um und habe da 
eben noch große Probleme
welche Parameter werden den mit welchen Daten belegt.

>uint8_t IndexOf( uint8_t BaseIndex, uint8_t Offset, uint8_t ArraySize )
>{
>  uint8_t result = BaseIndex + Offset;
>  if( result > ArraySize - 1 )
>    result = result - ArraySize - 1;
>
>  return result;
>}

>und dann eben   ....
>   Index = MaxIndex( Values, 8 );
>   TempValue = Values[ IndexOf( Index, 6, 8 ) ];
>
>   ....

Danke
Peter

von Karl H. (kbuchegg)


Lesenswert?

Peter C. schrieb:
> Hallo Karl Heinz,
> kannst du mir kurz erklären was in den einzelnen Zeile läuft ich kriege
> es nicht in den Kopf - ich gehe noch nicht so lange mit C um und habe da
> eben noch große Probleme

Aufmalen hilft meistens
1
  +---+---+---+---+---+---+---+---+
2
  | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
3
  +---+---+---+---+---+---+---+---+
Der festgestellte Maximalwert sei im ELement 5 gewesen

also hier:
1
  +---+---+---+---+---+---+---+---+
2
  | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
3
  +---+---+---+---+---+---+---+---+
4
                        ^
5
                        |
und von dem jetzt 4 ELemente weiter
1
  +---+---+---+---+---+---+---+---+
2
  | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
3
  +---+---+---+---+---+---+---+---+
4
                        ^
5
                        |   1
6
7
  +---+---+---+---+---+---+---+---+
8
  | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
9
  +---+---+---+---+---+---+---+---+
10
                        ^
11
                        |       2
12
13
14
  +---+---+---+---+---+---+---+---+
15
  | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
16
  +---+---+---+---+---+---+---+---+
17
                        ^
18
    3                   |
19
20
  +---+---+---+---+---+---+---+---+
21
  | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
22
  +---+---+---+---+---+---+---+---+
23
                        ^
24
        4               |

Das richtige Ergebnis ist also 1. Der Arrayindex 1 ist genau 4 Elemente 
weiter als der Arrayindex 5 (in einem Array mit 8 Elementen)

Mal sehen was die Rechnerei sagt:
1
   BasisIndex, der war 5
2
3
   BasisIndex + Offset,  BasisIndex war 5, Offset war 4
4
                         macht zusammen 9
5
6
7
  +---+---+---+---+---+---+---+---+
8
  | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
9
  +---+---+---+---+---+---+---+---+
10
                        ^         .....#....#
11
                        |           8  |  9 |
12
13
9 wäre also hier:
14
[code]
15
  +---+---+---+---+---+---+---+---+
16
  | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
17
  +---+---+---+---+---+---+---+---+
18
                                  .....#....#
19
                                    8  |  9 |
20
21
                                          ^
22
                                          |
Jetzt hat das Array aber nicht so viele Elemente, es sind nur 8, der 
größte Index ist daher 7. D.h. die 2 Elemente, um die wir rechts 
überstehen, fangen wir wieder von vorne an zu zählen.
1
                                         
2
  +---+---+---+---+---+---+---+---+
3
  | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
4
  +---+---+---+---+---+---+---+---+
5
                        ^
6
    1   2               |

Und wir sind wieder am richtigen Ergebnis. Woher wissen wir, dass wir 2 
überstehen?
Na wenn unser Rechenergebnis sagt, wir wollen aufs Element 9 und das 
Array hat einen Maximalindex von 7 (weil es 8 Elemente lang ist), dann 
stehen wir um 9 - 7 Elemente über.
1
   5 + 4 - 8
2
3
       9 - 8
4
5
           1
stimmt auffallend (8 deswegen, weil das Array 8 Elemente lang ist und in 
C mit dem Index 0 zu zählen begonnen wird)


Ist wie bei einer Uhr: Minuten Zeigeer auf 53 und da noch 23 Minuten 
dazu, dann steht der Minutenzeiger auf  53 + 23 - 60 = 16

> welche Parameter werden den mit welchen Daten belegt.

Na komm.
Es gibt 3 Parameter
Einer heißt BaseIndex
Einer heißt Offset
und einer heißt ArraySize

Du kennst die Aufgabenstellung: Ausgehend von einem Index einen anderen 
Index finden, der davon eine gewisse Anzahl entfernt ist.

Welcher Parameter wird wohl was sein?




>   Index = MaxIndex( Values, 8 );
>   TempValue = Values[ IndexOf( Index, 6, 8 ) ];

Das ist genau dein Beispiel von weiter oben:

  Suche den Index des ArrayElementes, welches den größten Wert enthält
  (das macht MaxIndex)
  Und von diesem Index ausgehend, welches Index hat das Element, das 6
  Einträge danach kommt? (IndexOf macht das)
  Hol den Messwert, der zu diesem Index gehört. (Arrayzugriff)

> ich gehe noch nicht so lange mit C um und habe da eben noch
> große Probleme

Das hat weniger mit C zu tun, als mit dem Willen Papier und Bleistift zu 
benutzen und sich einfach mal eine Skizze zu machen und mit Zahlen zu 
jonglieren.

: Bearbeitet durch User
von H.Joachim S. (crazyhorse)


Lesenswert?

H.joachim Seifert schrieb:
> Ich gehe jetzt mal von Index 0..7 aus, 1..8 ist blöd :-)
> -suche das Maximum -> dessen Index ist z.b. bei dir 6 (orignal 7)
> -addiere zu diesem Index den Abstand zu dem Wert, den du suchst (bei dir
> 6),
> Ergebnis 12
> -ist der berechnete Index grösser als dein Array, ziehe die Array-Grösse
> (8) ab
> -jetzt hast du den richtigen Index: 4

Ich zitiere mich mal ausnahmsweise selbst :-)
Das wurde alles schon mehrfach vorgekaut....

von Peter C. (Gast)


Lesenswert?

Hallo,
sorry das ich Euch so damit belaste.
Danke für die erstklassige Erklärung - es liegt schon an "der Umsetzung 
der Gedanken in die Sprache C" und an dem Anfänger Depp, eben mir. Ich 
brauche halt manchmal eine Initialzündung ums zu kapieren.

Ich danke Euch für die Geduld.

Gruß
Peter

von Peter C. (Gast)


Lesenswert?

Hallo Karl Heinz,
ich weiß zwar nicht ob positive Rückmeldung erwünscht sind, allerdings 
möchte ich meinen Dank aussprechen.

Ich bin nochmal alles Schritt für Schritt durchgegangen und habe es nach 
der Initialzündung hinbekommen.
Zu der Gelegenheit habe ich noch ein paar Fehler gefunden die ich selbst 
bei meinem Array gemacht habe, zuvor aber durch den Compiler nie 
angemeckert wurde.
Nach Änderung der Zeile

>int MaxIndex( int Werte, int AnzahlWerte )
auf
int MaxIndex( int *Werte, int AnzahlWerte )

ging es perfekt.

Gruß
Peter

von Denny Z. (dennz)


Lesenswert?

Hallo Peter C.,

hast du evtl eine Liste für mich, welche Zeitwerte welchem Ölstand bzw. 
welcher Öltemperatur entsprechen?

Danke und Gruß
Denny

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.