C Fragen zu Arrays + Tabellenformat in Konsole ausgeben?

mxb1n

Cadet 4th Year
Registriert
Okt. 2017
Beiträge
124
Hallo zusammen,

ich programmiere zur Zeit ein Programm welches die Noten abfragt und davon den Durschnitt berechnet.

Es sieht z. Z. wie folgt aus:

Code:
int main()
{
int note[4] = {}, i, notensumme, gesamtanzahl =0;
float zahl1, zahl2, zahl3;

//Noteneingabe 
for(i=0; i<5; i++) {
    printf("Geben Sie die Note %d ein: ",i+1);
    scanf("%d", &note[i]);
    note [i] = (const int) note [i];
}
//Notenausgabe
for(i=0; i<5; i++) {
    printf("Note %d: %d Schueler\n", i+1, note[i]);
}
//Berechnung des Notendurchschnitts
notensumme=(note[0]+note[1]*2+note[2]*3+note[3]*4+note[4]*5);
gesamtanzahl=(note[0]+note[1]+note[2]+note[3]+note[4]);
zahl1=notensumme;zahl2=gesamtanzahl;zahl3=zahl1/zahl2;


//Ausgabe des Notendurchschnitts
printf("\nNotendurchschnitt: %.2f", zahl3);

    return 0;
}

Jetzt habe ich folgende Probleme.

1. Da der Notenschnitt ja durchaus eine Kommazahl darstellen kann, muss ich mit float-Variablen rechnen, welche ich ja in Zeile 19 "erstelle".
Wieso kann ich nicht von Anfang an mit float-Variablen rechnen, indem ich aus Zeile 3 das int zu einem float mache?
Bekomme dort dann den Fehler: "...main.c|17|error: array subscript is not an integer|".
Somit könnte ich mir nämlich die 3 Variablen aus Zeile 4 sparen.

2.Wenn ich die notensumme (Zeile17) u. gesamtanzahl (Zeile18) in eine Formel packe, bekomme ich ein falsches Ergebnis, liegt wohl daran, das note[*] ein Integer ist und das Ergebnis evtl. eine Kommazahl.
Zudem, gibt es eine elegantere Weise die note[1] bis note[4] zu addieren? Falls ich ja jetzt noch mehr Variablen hätte, wäre die Reihe noch wesentlich länger. Gibts da eine kürzere Schreibweise mehrere Variablen zu addieren?

3. Die Notenausgabe ab Zeile 13 soll normalerwerweiße in einer Tabelle geschehen. Wie folgt:
noten.jpg
Habe jetzt schon ewig gegoogelt, aber wie soll das gehen? Durch 2dimensionale Arrays?

ps.: Ich weiß der Code ist unsauber, möchte aber erstmal zum Ergebnis kommen, dann kann man ihn verschönern. :-)

Bin für jeden Tipp dankbar!
 
1. i darf kein float werden, weil du i nutzt, um auf dein array zuzugreifen. Deshalb der Fehler.
2. wenn deine Anzahl an Noten dynamisch ist, dann hast du sicher eine Variable dafür und dein Array ist entsprechend groß. Nennen wir sie iCountNotes.
Code:
notensumme=0;
for(i=0;i<iCountNodes;i++) notensumme+=node[i];
Der Rechenfehler kann von den unterschiedlichen Datenfehlern kommen, solange du den Rechenfehler nicht nennst, ist das schwierig zu erkennen, ohne selbst zu kompilieren.
3. Kommt drauf an. Nutzt du eine Ausgabebibliothek? Oder eine Textausgabe? Hier musst du mit den Möglichkeiten deines Ausgabemediums hantieren. Für Consolen-Ausgabe nutze am besten die Zeichen - | + um eine Tabelle zu erhalten. Zeichnen auf Console ist nicht empfehlenswert.
 
Du liegst dem selben Irrtum auf, dem ich auch zunächst aufgesessen bin, SoDaTierchen. (Oder du hast nur das *(i+1) vergessen.)
Das Arrays note enthält die Anzahl der Schüler, die die Note 1-5 erhalten haben. Ein aussagekräftigerer Name wäre empfehlenswert.
Wenn wie im Beispiel fünf Noten von 1-5 mögich sind, kann man das dann wie oben als
Code:
notensumme=0;
for(i=0;i<5;i++) notensumme+=(i+1)*note[i];
schreiben. Hast bspw. Drittelnoten, kannst du z.B. mit zwei Arrays einmal die Anzahl und einmal den Notenwert angeben:
Code:
float notenwert[13] = {1, 1.3, 1.7, 2, 2.3, 2.7, 3, 3.3, 3.7, 4, 4.3, 4.7, 5};
notensumme=0;
for(i=0;i<13;i++) notensumme+=anzahl_note[i]*notenwert[i];
Zur Ausgabe einer "Tabelle" in der Konsole bieten sich Tabulatorzeichen an.
 
Hallo,
also das Programm läuft jetzt soweit.
Vielen Dank schonmal für die Hilfe!

Habe jetzt alles zu float-Variablen gemacht, außer die Variable i, die bleibt ein Integer.
Die Rechenformel konnte ich nun auch kürzen und etliche Variablen dadurch entfernen.

Nur falls ich eine Tabelle erstellen will, bekomme ich sie nicht so hin, wie oben auf dem Bild vorgegeben, da ich ja mit einer Schleife arbeite während der printf-Ausgabe.
Könnte höchstens 2 Printf-Ausgaben machen, einmal für "Note 1 | Note 2| Note 3 |..." und die nächste Spalte dann mit den Anzahl der Noten jeweils, nur sobald eine Zahl dann 2-stellig wird, steht die Zahl etwas verrückt und alles passt nicht mehr. Habe es jetzt so gemacht:

Code:
//Notenausgabe
printf("\n---------------------------------------------------"
       "--------------------------------------------------------------------\n");
for(i=0; i<5; i++) {
    printf("Note %d: %1.0f Schueler | ", i+1, note[i]);
}
printf("Gesamt: %.0f |\n------------------------------------------------"
       "-----------------------------------------------------------------------", notensumme);

Schreibt man das so in den Quellcode, wenn man diese Striche (-----) machen will? Sieht etwas merkwürdig aus.

Achso, und noch zwei 'Newbie'-Fragen; Wie mache ich eine Arraygröße konstant?
Mann kann ja %d und %i schreiben, für den Integer, ist es einfach nur Stilmittel, oder hat das einen Grund?
 
Zuletzt bearbeitet:
@simpsonsfan: Du hast vollkommen recht, ich lag da wirklich im Irrtum. Irgendwann wird man sprechende Namen gewohnt und macht sich weniger Mühe Code mit ungünstigen Bezeichnungen zu verstehen ... eigentlich schade.

@mxb1n:
Schau dir mal https://en.wikipedia.org/wiki/Scanf_format_string an, da wird der Unterschied zwischen %d und %i gut erklärt und auch andere Platzhalter erwähnt. Ist zwar für die Eingabe, funktioniert analog aber auch für die Ausgabe.

Wie man die Ausgabe gestaltet ist eigentlich jedem selbst überlassen. Ich lasse sie gerne offen im Quelltext stehen und möglichst kompakt, weil man dann im Quellcode gleich lesen kann, was passieren soll. Studienkollegen von mir haben die gerne mathematisch umschrieben, das hat zwar den Speicherplatz ein wenig geschont, war aber nach ner Woche nicht mehr lesbar.

Ein Beispiel, was sehr leicht als Quellcode lesbar ist:
Code:
printf("\n+-----------------------------------------+");
printf("\n| Note   | 1  | 2  | 3  | 4  | 5  | Summe |");
printf("\n+-----------------------------------------+");
printf("\n| Anzahl | %2i | %2i | %2i | %2i | %2i | %3i   |", note[0], note [1], note [2], note [3], note [4], notensumme);
printf("\n+-----------------------------------------+");

Ein anderes Beispiel, was etwas "programmierter" aussieht, aber nicht mehr so gut lesbar ist:
Code:
void printHorizontalTableDelimeter() {printf("\n+-----------------------------------------+");}
...
printHorizontalTableDelimeter();
printf("\n| Note   | 1  | 2  | 3  | 4  | 5  | Summe |");
printHorizontalTableDelimeter();
printf("\n| Anzahl |");
for(int i=0;i<5;i++) {printf(" %2i |",note[i]);}
printf(" %3i  |", notensumme);
printHorizontalTableDelimeter();
...

Möglicherweise sind Tippfehler enthalten, aber prinzipiell sollen die Beispiele zeigen, dass es oft sogar sinnvoller ist, String-Ausgaben direkt in den Code zu pflastern. Zumindest solange sich dadurch keine offensichtlichen Probleme ergeben, wie z.B. bei der Mehrsprachigkeit auftreten können.
 
Zurück
Oben