DerEinfaeltige
Senior Dabei seit: 11.02.2015 Mitteilungen: 2596
Beitrag No.7, eingetragen 2020-12-01
Da gefordert ist, vernünftig lesbaren und kommentierten Code zu schreiben. sollte man das Problem auch in Teilprobleme zerlegen.
1. Dateneingabe und Fehlerbehandlung.
Da die Dateneingabe mit scanf bekanntlich so ihre Tücken hat (bspw. das "Flushen" eines fehlerhaften Eingabestrings), sollte man dieses Problem zunächst unabhängig von der eigentlichen Programmlogik lösen.
2. Die Programmlogik (Ausgabe des Dreiecks).
Hier bietet es sich vielleicht an, zunächst eine Hilfsfunktion zum Schreiben einer einzelnen Zeile mit gegebener Zahl Leerzeichen (alternativ Breite) und gegebener Zahl Doppelkreuze zu implementieren.
Die Dreiecksfunktion muss sich dann nur um die Berechnungen kümmern.
Auf diese Art kommt jede Funktion mit etwa 5-10 Zeilen Code aus, der Code ist auch mit minimaler Kommentierung klar verständlich und die Fehlersuche wird stark vereinfacht.
----------------- Why waste time learning when ignorance is instantaneous?
- Bill Watterson -
viertel
Senior Dabei seit: 04.03.2003 Mitteilungen: 27684
Herkunft: Hessen
Beitrag No.8, eingetragen 2020-12-01
2020-11-30 21:46 - HartlPet in Beitrag No. 3 schreibt:
So weit bin ich, wie schaffe ich es dass er wieder "zurückzählt"
Indem du im passenden Moment die Variable stepsize negierst.
Anmerkung zum Code hier reinstellen
Deinen Code hier als Bild reinzustellen ist keine gute Idee.
Der Code kann von niemandem verwendet/kopiert werden, sondern man muß ihn mühsam abtippen.
Es gibt keine Zeilennummern, auf die man sich mit Bemerkungen beziehen kann.
Klicke auf das [num] von [Quelltext [num.] unterhalb des Eingabefensters und kopiere dann deinen Code rein. Ergebnis siehe meinen (geänderten) Beitrag #4.
Folgende Antworten hat der Fragesteller vermutlich noch nicht gesehen.
DerEinfaeltige
Senior Dabei seit: 11.02.2015 Mitteilungen: 2596
Beitrag No.11, eingetragen 2020-12-02
Er meint damit, es negativ zu machen.
Weiterhin fehlen die Kommentare.
Wenn man sich in jedem Schritt aufschreibt, was genau passieren soll, lösen sich Probleme wie die Programmlogik der triangle-Funktion mehr oder weniger von alleine.
Tipp:
Du könntest zum Zeichnen des Dreiecks zwei Schleifen nutzen.
Eine für die obere Hälfte und eine für die Untere.
PS.: Wenn du die Quelltextumgebung nutzt, könntest du die Programmiersprache angeben.
C
// EDIT 1/4// ich habe oben die Sprache C ergänzt// dafür hattest du hier die Zeilennumerierung weg gelassen// zweimal den gleichen Code brauchen wir ja nicht, habe diesen hier somit entfernt
PPS.: Warum liest du die Zahlen als float ein und nicht als Integer?
----------------- Why waste time learning when ignorance is instantaneous?
- Bill Watterson -
2020-12-02 19:35 - DerEinfaeltige in Beitrag No. 11 schreibt:
Tipp:
Du könntest zum Zeichnen des Dreiecks zwei Schleifen nutzen.
Eine für die obere Hälfte und eine für die Untere.
Das bedingt Code-Redundanz (praktisch den gleichen Code nochmal aufschreiben), die es grundsätzlich zu vermeiden gilt. Denn Änderungen/Korrekturen (z.B. '$' statt des '#' ausgeben, oder führende '.' statt des Leerzeichens) müssen dann an beiden Stellen vorgenommen werden.
Die Zeilen 30..34 würde ich so schreiben:
C
if(i ==(rows+1)/2)
{
stepsize =-stepsize;// ab jetzt werden die '#' wieder reduziert
}
count += stepsize;
Überlege dir, was diese Änderung bewirkt!
Und erst dann probiere es aus😎\(\endgroup\)
2020-12-02 19:35 - DerEinfaeltige in Beitrag No. 11 schreibt:
Tipp:
Du könntest zum Zeichnen des Dreiecks zwei Schleifen nutzen.
Eine für die obere Hälfte und eine für die Untere.
Das bedingt Code-Redundanz (praktisch den gleichen Code nochmal aufschreiben), die es grundsätzlich zu vermeiden gilt.
So wahnsinnig redundant finde ich das jetzt nicht.
C
void fill(unsignedint n,char c){unsignedint i;for(i =0; i < n;++i)printf("%c",c);}void print_row(int i,unsignedint rows,unsignedint stepsize){unsignedint total = rows /2* stepsize +1;unsignedint empty = total -(i * stepsize +1);
fill(empty,' ');
fill(total - empty,'#');printf("\n");}void triangle(unsignedint rows,unsignedint stepsize){int i;for(i =0; i <= rows/2;++i)
print_row(i,rows,stepsize);for(i = rows/2-1; i >=0;--i)
print_row(i,rows,stepsize);}
----------------- Why waste time learning when ignorance is instantaneous?
- Bill Watterson -
viertel
Senior Dabei seit: 04.03.2003 Mitteilungen: 27684
Herkunft: Hessen
Beitrag No.16, eingetragen 2020-12-03
@DerEinfaeltige
Touché 😎
Aber „in einem Rutsch“ ist es doch irgendwie eleganter (und auch noch vollständig kommentiert). Außerdem 2 Varianten der triangle-Funktion.
C
void fill(int n,char c)/*
n-mal das Zeichen c ausgeben
*/{for(int i=0; i<n ; i++)printf("%c", c);}// fill//----------------------------------------------------------------void printrow(int empty,int count)/*
eine Zeile des Dreiecks ausgeben
empty : wie oft das Füllzeichen
count : wie oft das darstellende Zeichen
*/{
fill(empty,'.');// Füllzeichen
fill(count,'#');// das Zeichen für das Dreieckprintf("\n");}// printrow//----------------------------------------------------------------void triangle(int rows,int stepsize)/*
Das Dreieck ausgeben
rows : wie viele Zeilen
stepsize : wie viele Zeichen pro Zeile mehr/weniger ausgeben
*/{int maxchar =1+(rows-1)/2*stepsize;int count =1;// Zähler für auszugebendes Zeichenint i;// Zähler für Schleifendurchgang (Zeile)for(i=0; i<rows ; i++){
printrow(maxchar-count, count);if(i ==(rows-1)/2)// in der Mitte angekommen ?
stepsize =-stepsize;// Zählung umkehren
count += stepsize;// Zähler für nächste auszugebende Zeile}}// triangle//----------------------------------------------------------------void triangle2(int rows,int stepsize)/*
wie traiangle()
Aber die Berechnung von count erfolgt mit etwas Mathematik
Es wird die "Knickfunktion" der abs()-Funktion ausgenutzt
Einfach mal drüber nachdenken
*/{int mitte =(rows-1)/2;int maxchar =1+ mitte*stepsize;int count;int i;for(i=0; i<rows ; i++){
count =1+ stepsize*(mitte -abs(i-mitte));
printrow(maxchar-count, count);}}//----------------------------------------------------------------int main(void){
triangle(7,3);
triangle2(7,3);return0;}// main