www.mikrocontroller.net

Forum: PC-Programmierung Funktion Vergleichen läuft nicht


Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

kann mir einer schreiben warum die Funktion nicht geht?

Die Funktion soll ein Array("ergebnis") vergleichen. Die niedrigste 
Adresse des arrays soll dann am Schluss in der Variablen k stehen. 
Verstehe einfach nicht warum da nichts rauskommt. i und k sind als 
Integer definiert. Auch die Werte im Array stimmen. Liegt nur an der 
Funktion.

for(i = 2; i <= 32; i++)
{
  if(ergebnis[i] < ergebnis[k])
  {
  k = i;
  }
}
Gruss
Johannes

Autor: Werner A. (homebrew)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
machst du auch ein return(k)?

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
die Funktion steht in einem größeren Funktionsblock. Ich arbeite bzw. 
will gleich weiter arbeiten mit dem k in der gleichen Hauptfunktion. Das 
ganze Programm läuft aber nicht, weil die Funktion es nicht hinbekommt, 
den niedrigsten Wert daraus zu bekommen.

Autor: ... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

wie ist denn ergebnis definiert? Hast Du eventuell vergessen k zu 
initialisieren?

So sollte das eigentlich gehen:
char ergebnis[32];
int i, k;

k = 0;
for(i = 1; i < 32; i++) {
  if(ergebnis[i] < ergebnis[k]) {
    k = i;
  }
}

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hmm... läuft damit auch nicht, vielleicht habe ich ja auch einen 
denkfehler.

bsp.

ergebnis[0] = 34
ergebnis[1] = 45
ergebnis[2] = 0
ergebnis[3] = 5

so sieht mein Array beispielhaft aus. Ist in wirklichkeit wesentlich 
größer. Kapier nicht warum er das nicht erfassen kann.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Den kleinsten Wert eines Array kannst Du so bestimmen:
k = ergebnis[0]; 

for (i = 0; i < 32; i++)
  if (ergebnis[i] < k)
    k = ergebnis[i];

Und den Index dieses Elements bestimmst Du so:
k = ergebnis[0]; 
j = 0;

for (i = 0; i < 32; i++)
  if (ergebnis[i] < k)
    {
    k = ergebnis[i];
    j = i;
    }

Entscheidend ist, daß k (als kleinster Wert) und j (als Index des 
kleinsten Wertes) vor dem Durchsuchen des Arrays mit sinnvollen Werten 
initialisiert werden. Beim Index ist das einfach, 0 ist auf jeden Fall 
ein gültiger Arrayindex. Beim Vergleichswert kann der Wert eines 
beliebigen Elementes des Arrays verwendet werden - denn der liegt 
garantiert im Wertebereich aller Arrayelemente.

Autor: ... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Rufus:
Du kannst den Startwert der for-Schleife in Deinen beiden Beispielen auf 
1 setzen, da die if-Bedingung für i==0 niemals wahr ist. Spart halt 
einen Schleifendurchlauf. Und im Endeffekt hast Du dann ziemlich genau 
den selben Code wie ich.

@Johannes:
Wenn ich mir Deinen Orginalcode anschaue, scheint mir Du hast ein 
Verständnisproblem wie der Wertebereich für Arrayidizes ist. Schau Dir 
die Beispiele von Rufus und mir nochmal genau an, insbesondere in meinen 
Beispiel die erste Zeile und in allen Beispielen die Abbruchbedingung 
der for-Schleife!

CU

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
... - Da hast Du natürlich recht.
Um den Algorithmus zu verstehen, halte ich es jedoch für sinnvoll, 
zunächst auf Optimierungen zu verzichten.
Die kann man sich dann immer noch einfallen lassen ...

Autor: ... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
... - Da hast Du nun wieder recht :)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Johannes wrote:
> so sieht mein Array beispielhaft aus. Ist in wirklichkeit wesentlich
> größer. Kapier nicht warum er das nicht erfassen kann.

DIe Antwort darauf ist ganz einfach:
Der Rechner macht, was du programmiert hast.
Wenn also das Ergebnis nicht dem entspricht, was du haben
möchtest, dann deshalb weil du einen Fehler im Programm hast.

Den wird dir aber niemand zeigen können, solange du nicht
etwas mehr von deinem Programm herzeigst..

> die Funktion steht in einem größeren Funktionsblock.

Das hört sich nicht besonders gut an. Das klingt eher wieder
nach einem Standardproblem: Zu grosse Funktionen, die keiner
mehr überblicken kann.

Und ... hat recht. Der Originalcode sieht wirklich so aus,
als ob du das Arrayhandling in C nicht wirklich verstanden
hast.

Bei der Deklaration eines Arrays gibt man die Anzahl der
Elemente im Array an

 int  a[6];

a hat 6 Elemente. Diese tragen die Indizes 0, 1, 2, 3, 4, 5
Zähl sie nach, es sind genau 6. Der höchste Arrayindex in einem
Array ist daher immer um 1 kleiner als die Anzahl der Elemente die
man bei der Variablendefinition angegeben hat. Ein Zugriff auf
a[6] wäre definitiv ein schwerer Fehler.

Konsequenterweise lautet eine Schleife, die alle Elemente von a
besucht, so:

  for( i = 0; i < 6; i++ )
    // mach was mit a[i]

Eine for-Schleife nach dem Muster

  for(i = 2; i <= 32; i++)

auf einem Array, deutet auf ein Nichtverständnis von Arraybehandlung
in C hin:
* Es ist ungewöhnlich, dass die Schleife mit 2 beginnt.
  Normalerweise beginnt die Schleife mit 0, weil 0 das erste
  Array Element ist. In deinem Fall kann die Schleife mit 1, also
  dem zweiten Array Element beginnen, weil ja das erste Element
  einfach mal als das temporär kleinste Element angenommen werden
  kann.
  Eine 2 als Anfangswert ist normalerweise ein Indiz für die
  'Array Indizes beginnen bei 1' Fraktion. Das wäre grober Unfug.
  Gewöhn dich daran, dass in C bei 0 zu zählen begonnen wird und
  du hast in Zukunft weniger Probleme
* das <=
  wenn eine for-Schleife zur Bearbeitung von Arrays nicht nach
  dem Muster

  for( i = 0; i < Anzahl_Array_Element; i++ )

  aussieht, dann sollten sofort alle Alarmglocken bimmeln. Denn
  meistens ist dann irgendwas faul. Der häufigste Fall ist das
  Nichtverstehen, dass aus der Tatsache das Array Inidzes bei 0
  beginnen folgt, das der höchste zulässige Index Wert immer um
  1 kleiner als die Anzahl der Elemente ist

  int b[6];

  for( i = 1; i <= 6; i++ )
    b[i] = 5;

  ist nun mal definitv falsch. Es gibt kein Element b[6]!


In seltenen Fällen kommt es tatsächlich vor, dass ein <= klarer
die Absicht hinter der Schleife ausdrückt. Aber selbst dann ist
es oft besser dies durch ein < auszudrücken und dafür den Vergleichswert
zu korrigieren. Und sei es nur deshalb, weil die Form der Schleife
so ist, wie man sich daran gewöhnt hat und schnell und ohne gross
Nachzudenken analysieren kann.
Die Standardform
   for( i = 0; i < 6; i++ )
liefert für i alle Zahlen von 0 bis 5. Also genau alle Zahlen
die als gültige Indizes für ein Array der Größe 6 gelten.
Und diese 6 findet sich in der for-Schleife wieder.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> kann mir einer schreiben warum die Funktion nicht geht?

Definiere "nicht geht"? Was passiert?

> Verstehe einfach nicht warum da nichts rauskommt.

Wie "nichts"? Irgendetwas muß ja herauskommen. Zeige doch mal ein Array, 
mit dem du es getestet hast und den Wert, den k danach hat.

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe mittlerweile den Code von Rufus miteinfließen lassen und meine 
Abfrage ein bissel noch geändert. Läuft jetzt einwandfrei.
Danke euch allen.

Autor: Wegstabenverbuchsler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
und was war dein Fehler?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.