Archiv verlassen und diese Seite im Standarddesign anzeigen : C Aufgabe zu Mehrdimensonalen Felder
SteveKanonfreak
10.07.2011, 13:56
Hallo,
ich habe ein Problem bei eine Programmieraufgabe und zwar mit der Programmiersprache C.
Wir müssen ein C Programm schreiben, bei dem 2 Zahlen eingelesen werden sollen und zwar n für die Anzahl der Konditoren und k für die Anzahl der Torten. Danach soll jeder Konditor eine Note von 1-6 für alle Torten abgeben. So weit so gut bis hier her hab ich es geschafft, doch nun müssen wir nun die beste Torte durch den Durschnitt ermitteln:
z.b:: 3 Konditoren dann ist der Durchschnitt die Noten zusammengezählt durch die Anzahl die Konditoren. Nun das ist auch nicht so schwer nun sollen wir aber die beste ermitteln und hier komm ich einfach nicht weiter.
Als nächste Aufgabe muss man dann auch noch den Konditor mit der niedrigsten Meinung ermitteln. 1 ist die schlechtetste und 6 die Beste.
#include <stdio.h>
main(){
int n,k,l=1,m=1,j,i,a=1,b=1;
int feld [m][l];
printf("Geben sie die Anzahl der Konditoren an:\n");
scanf("%i",&n);
printf("Geben sie die Anzahl der Torten an:\n");
scanf("%i",&k);
for(j=1;j<=n;j++){
printf("Konditor %i geben sie ihre Meinung (Zahl von 1 - 6) zur %i.Torte ein:\n",b,a);
for(i=1;i<=k;i++){
scanf("%i",&feld[m][l]);
a++;
l++;
}
a=1;
m++;
b++;
l=1;
}
}
a und b ist unwichtig. Sie sind nur da um zeigen, welche Konditor gerade dran ist zu bewerten bzw. welche Torte bewertet werden muss.
l und m hab ich deswegen benutzt, weil ich n und k später für den Durchschnitt noch brauche und deswegen nicht will, dass sie verändert werden.
Ich hoffe ihr könnt mir helfen, denn hab schon alles ausprobiert, was mir eingefallen ist.
Merke dir doch einfach die Torte mit dem höchsten Durchschnittsergebnis und prüfe bei jeder neuen Durchschnittsbildung ob das resultierende Ergebnis besser als das gerade aktuelle Best-Ergebnis ist. Sollte es so sein dann speicherst du dir einfach die neue Torte als Beste, ansonsten behälst du die vorherige Torte einfach so im Speicher.
... halt recht trivial, musst dir nur eine temporäre Variable erzeugen.
SteveKanonfreak
10.07.2011, 14:13
Oh man! Warum bin ich da nicht selber drauf gekommen.
Auf jeden Fall vielen Dank. ;)
MaChiMiB
10.07.2011, 14:26
Ja, genau so wird das gemacht ;)
Aber Achtung, was mir in dem Quellcode auffällt:
Du erzeugst dir ein zweidimensionales Feld der Größe [1][1]. Du reservierst dir damit Speicherplatz im Ram für eine Note von einem Konditor.
Später erhöhst du zwar m und l aber der Speicherplatz wird nicht automatisch erhöht! Es wird also einfach nach dem von dir reservierten Speicherbereich die anderen Noten geschrieben. Dieser RAM bereich ist aber nicht für dich reserviert. Er kann von anderen Programmen oder Windows überschrieben werden.
Du kannst Glück haben, das dieser Bereich zufällig unverändert bleibt. Es kann aber sein, dass er mit irgendwelchen Werten überschrieben wird!
Bei kleineren Datenmengen (viel kleiner als 1MB, was hier der Fall ist) überlegt man sich vorher, wie viele Daten man ungefähr Speichern will. Also zB 20 Konditoren und 100 Torten als Maximum. Dann wird ein Feld[20][100] erstellt. So reservierst du dir dann auf jeden Fall genung Speicherplatz, der dann nur dir gehört.
Falls du dann nur 10 Konditoren und 40 Torten hast, ist der restliche reservierte Speicherplatz verschwendet, aber das ist eigentlich egal.
Also: Immer eine maximale Feldgröße festlegen. Diese muss auf jeden Fall konstant sein und kann nach dem erstellen des Feldes nicht mehr verändert werden.
Alternative: Dynamische Speicherverwaltung: siehe malloc bzw realloc (ist aber etwas komplizierter)
SteveKanonfreak
10.07.2011, 14:33
Stimmt du hast Recht.
Ich kann doch einfach das Feld erst dann deklarieren, wenn n und k eingelesen wurden?
#include <stdio.h>
main(){
int n,k,l=1,m=1,j,i,a=1,b=1;
printf("Geben sie die Anzahl der Konditoren an:\n");
scanf("%i",&n);
printf("Geben sie die Anzahl der Torten an:\n");
scanf("%i",&k);
int feld[n][k];
MaChiMiB
10.07.2011, 14:43
Nein das geht nicht. Die Feldgröße muss konstant sein.
1) Du legst dir ein großes Feld an: feld[1000][1000]
2) Du liest die Anzahl der Konditoren und Torten ein: n und k
3) Du beschreibst das große Feld nur bis feld[n][k], also von feld[1][1] bis feld[n][k]
4) Alle Speicherplätze über [n][k] sind zwar für dich reserviert, werden von dir aber nicht benutzt.
Eigentlich musst du in deinem Quellcode (vom 1. Post) nur "int feld [m][l];"
durch" int feld [1000][1000];" ersetzen.
Die Felder mit dynamischer Größe anlegen ist ein bisschen schwerer, dazu musst du dich mit Zeigern (Pointer) auskennen.
edit: Ganz generell bei C (nicht bei C++): Variablen(auch Felder) können nur VOR dem eigenlichen Programmcode "erstellt" (deklariert) werden.
kuddlmuddl
10.07.2011, 16:55
Alternativ benutzt man keine statische Datenstruktur wie ein Array sondern eine Dynamische wie eine Liste
edit: Ganz generell bei C (nicht bei C++): Variablen(auch Felder) können nur VOR dem eigenlichen Programmcode "erstellt" (deklariert) werden.
Falls du damit meinst, daß alle lokalen Variablen ganz oben in der Funktion deklariert werden müssen, das ist meines Wissens schon seit C99 nicht mehr so.
IceMatrix
10.07.2011, 19:00
@MaChiMiB: Betrifft C90, ab C99 spielt es keine Rolle mehr wo die Variable deklariert wird. Wenn der Quellcode über einen C++ Compiler kompiliert wird ist es auch egal.
Mit so Zeug wie "int feld [1000][1000]" sollte man übrigens vorsichtig sein. Das kann ganz schnell zu einem Stack Overflow führen.
Prinzipiell wenn das eigentliche Voting jedes einzelnen Konditors egal ist (also es nur um den Durchschnitt geht), dann brauchst du hier gar kein mehrdimensionales Array.
Es reicht dann aus ein Array zu erstellen, das genau so viele Einträge hat wie es Torten gibt. Bei jedem Vote addierst du zum entsprechenden Eintrag die Note hinzu.
In einem abschließenden Schritt dividierst du dann alle Einträge durch die Zahl der Konditoren und schon hast du das Ergebnis.
MaChiMiB
10.07.2011, 19:29
Wieder was gelernt, danke.
Mit den verschiedenen C Standards kenn ich mich nicht so aus. Das blöde Visual Studio verlangt bei mir die Deklarationen am Anfang der Funktionen.
Das mit dem [1000][1000] ist echt schon gefährlich. Ich glaub die default Stack-Größe ist im unteren MB-Bereich und mit dem Feld ist man ja schon bei 4MB.
Wenn man schon in C programiert und multidimensonalen dynamische Arrays braucht (für die Lösung diese Problems nicht notwendig) dann richtig:
http://c-faq.com/~scs/cclass/int/sx9b.html
Bitte nicht feld[1000][1000]. Das gibt mir einen Stich ins Herz.
Und keine Angst form * ;)