• Hallo liebe Userinnen und User,

    nach bereits längeren Planungen und Vorbereitungen sind wir nun von vBulletin auf Xenforo umgestiegen. Die Umstellung musste leider aufgrund der Serverprobleme der letzten Tage notgedrungen vorverlegt werden. Das neue Forum ist soweit voll funktionsfähig, allerdings sind noch nicht alle der gewohnten Funktionen vorhanden. Nach Möglichkeit werden wir sie in den nächsten Wochen nachrüsten. Dafür sollte es nun einige der Probleme lösen, die wir in den letzten Tagen, Wochen und Monaten hatten. Auch der Server ist nun potenter als bei unserem alten Hoster, wodurch wir nun langfristig den Tank mit Bytes vollgetankt haben.

    Anfangs mag die neue Boardsoftware etwas ungewohnt sein, aber man findet sich recht schnell ein. Wir wissen, dass ihr alle Gewohnheitstiere seid, aber gebt dem neuen Board eine Chance.
    Sollte etwas der neuen oder auch gewohnten Funktionen unklar sein, könnt ihr den "Wo issn da der Button zu"-Thread im Feedback nutzen. Bugs meldet ihr bitte im Bugtracker, es wird sicher welche geben die uns noch nicht aufgefallen sind. Ich werde das dann versuchen, halbwegs im Startbeitrag übersichtlich zu halten, was an Arbeit noch aussteht.

    Neu ist, dass die Boardsoftware deutlich besser für Mobiltelefone und diverse Endgeräte geeignet ist und nun auch im mobilen Style alle Funktionen verfügbar sind. Am Desktop findet ihr oben rechts sowohl den Umschalter zwischen hellem und dunklem Style. Am Handy ist der Hell-/Dunkelschalter am Ende der Seite. Damit sollte zukünftig jeder sein Board so konfigurieren können, wie es ihm am liebsten ist.


    Die restlichen Funktionen sollten eigentlich soweit wie gewohnt funktionieren. Einfach mal ein wenig damit spielen oder bei Unklarheiten im Thread nachfragen. Viel Spaß im ngb 2.0.

C++ kleinste Zahl ausgeben

Sp1xx

NGBler

Registriert
9 Okt. 2013
Beiträge
643
Ort
Bavaria
Hallo zusammen,

ich bin seit ein paar Tagen daran ein bisschen C++ zu lernen. Nun stehe ich aber vor einem Hindernis:

Aufgabe:
Schreibe eine Funktion, in der beliebig viele positive Zahlen eingelesen werden und die kleinste an die aufrufende Funktion zurückgegeben wird. Realisiere dies mit einer Schleife, die als Abbruchkriterium die Eingabe von 0 hat.

So habe ich angefangen:

[src=cpp]#include <iostream>
#include <iomanip>

using namespace std;


int main()
{

int i, min=0;

while(i>0)
{
cout<<"Geben sie eine Zahl ein:";
cin>>i;
if(i == 0) break;
if (i<i) min=i;

}


cout<<"Die kleinste Zahl ist:"<<min;

cin.get();


}[/src]


Schlagt mich nicht wenn das totaler Humbuk ist, ich tu mir mit Schleifen noch extrem schwer!
 
Zuletzt bearbeitet:

Larius

OutOfOrder

Registriert
12 Juli 2013
Beiträge
5.792
Paar Kleinigkeiten die mir auffallen:

*) min sollte deklariert werden. Wird als 1te Zahl nämlich direkt 0 ausgegeben kann irgendein Wert in min stehen und du wunderst dich woher das kommt. Sprich ein min = 0; ist an dieser Stelle zu empfehlen ;)
*) i>0 && i != 0 ist doppelt gemoppelt, weil beide Ausdrücke liefern false zurück wenn i gleich 0 ist. Da kannst du einen davon weglassen und sparst dir etwas Tipparbeit ;)
*) Momentan hast du das Problem das du min auf 0 setzt wenn du 0 eintippst zum Beenden der Schleife. Stattdessen könntest du folgendes Konstrukt verwenden:

Code:
while(true)
{
    cout<<"Geben sie eine Zahl ein:";
    cin>>i;
    if(i == 0) break;
    if (i<i) min=i;
}

while(true) ist eine Endlosschleife. Mit break; kannst du aus einer Schleife jedoch herausspringen. Somit ist der zuletzt niedrigste, gültigste, Wert in min drinnen und deine Ausgabe stimmt wieder ;)

LG
 

Sp1xx

NGBler

Registriert
9 Okt. 2013
Beiträge
643
Ort
Bavaria
  • Thread Starter Thread Starter
  • #3
Hallo,

danke schon einmal. Habe deine Tipps mal berücksichtigt und angepasst. Leider klappt das ganze noch nicht so ganz:

Anhang anzeigen 19734

unsicher bin ich mir auch bei dieser Stelle:

[src=cpp]if (i<i) min=i;[/src]


Der sagt mir doch:
Falls der eingegebene Wert i kleiner als der alte Wert i ist, wird min gleich dem eingegebenen Wert gesetzt.
Wenn i quasi größer ist passiert garnichts und es geht von vorne los?
 

War-10-ck

střelec
Veteran

Registriert
14 Juli 2013
Beiträge
5.952
Ort
Schießstand
Ich hab jetzt deine erste Codeversion nicht gesehen wenn du aber (i<i) schreibst vergleicht er zweimal den selben Wert was logischerweise immer false gibt. Willst du jeweils alten und neuen Wert vergleichen leg doch i_old und i_new an. Zumal es gut wäre wenn du dir von vornherein angewöhnst sprechende Variablen zu verwenden: schreib input statt i. Wenn du einmal mit dem abgekürze anfängst kann das nachher ganz dolle unübersichtlich werden.

Edit: Bzw. du hast ja den alten Wert schon in min. Also vergleich if (i<min) min=i;
 

BurnerR

Bot #0384479

Registriert
20 Juli 2013
Beiträge
5.507
"if(i < i)"? Bro, please.

Schreib mal in deutscher Sprache auf wie dein Plan für diese Aufgabe ist. Wenn du nicht weißt was du eigentlich machen willst kannst du es erst recht nicht in Code gießen. Also, wie geht sowas wohl prinzipiell?

Noch was:
"und die kleinste an die aufrufende Funktion zurückgegeben"
Zurückgeben heißt nicht mit cout ausgeben ;-).
 

Sp1xx

NGBler

Registriert
9 Okt. 2013
Beiträge
643
Ort
Bavaria
  • Thread Starter Thread Starter
  • #6
Danke für die Hilfe.

Wie schon gesagt das ist mein dritter Tag mit C++ und ich bitte die offensichtlichen Fehler zu entschuldigen.


[src=cpp]#include <iostream>
#include <iomanip>

using namespace std;


int main()
{

int input;
int min=0;

while(input>0)
{

cout<<"Geben sie eine Zahl ein:";
cin>>input;
if(input == 0) break;
if (input<min) min=input;


}


cout<<"Die kleinste Zahl ist:"<<min;

cin.get();


}[/src]

Der veränderte Code gibt mir nun weiterhin den Wert 0 aus.

Ich verstehe auch nicht die Notwendigkeit des breaks:

[src=cpp]if(input == 0) break;[/src]

ich habe doch schon in der while Schleife definiert das es nur so lange weiter gehen soll solange der input größer als 0 ist. Sobald dies nicht der Fall ist springt das Programm doch automatisch zu:

[src=cpp]cout<<"Die kleinste Zahl ist:"<<min;[/src]


Entschuldigt meine Unwissenheit.
 
Zuletzt bearbeitet:

War-10-ck

střelec
Veteran

Registriert
14 Juli 2013
Beiträge
5.952
Ort
Schießstand
Ich kenn mich übrigens auch nicht mit C++ aus. Was mir da jetzt auffällt:
int input; ist nicht definiert. Initialisiere die Variable mal mit irgendeinem dir logisch erscheinenden Wert.

Warum dass so nicht funktionieren kann: Du fängst immer mit min=0 an. Dann hat der Nutzer die Möglichkeit Werte größer als 0 einzugeben. Damit bleibt null immer die kleinste Zahl. Was willst du denn konkret erreichen? Sollen negative Zahlen überhaupt verboten werden?

Bevor ich dir hier jetzt ein laufendes Stück Code hinschreibe, wo du auch nichts von hast. Schreibst du hier mal ganz genau auf unter welchen Ramenbedingungen dein Programm laufen soll. Also was darf der Nutzer alles eingeben. Mit welchen Werten soll gestartet werden. Sowas wie int input; ist immer Mist. Da ist input nämlich undefiniert und du hast keinen Einfluss drauf was drinsteht.

Edit: Für Unwissenheit brauchst du dich nicht zu entschuldigen. Frag so oft nach wie du brauchst um es zu verstehen.

Edit2: Der Break ist bei dir momentan nicht notwendig es sei denn du willst wirklich abbrechen wenn der Nutzer 0 eingibt. Bei dem Vorschlag von Larius war er zwingend um aus der while(true) Endlosschleife herauszukommen. Das ist imho aber eh eine eher unsaubere Art breaks zu benutzen. Sauberer ist es in der while() Schleife eine Endliche Bedingung zu verwenden.
 
Zuletzt bearbeitet:

Sp1xx

NGBler

Registriert
9 Okt. 2013
Beiträge
643
Ort
Bavaria
  • Thread Starter Thread Starter
  • #8
Danke für die qualifizierte Antwort.

Die Anforderungen:

- nur positive Zahlen (keine kleiner 0)
- Es sollen so viele Zahlen wie man möchte eingeben
- Die Zahlen sollen positive ganze Zahlen sein
-> Bis eine Null eingegeben wird womit das Programm beenden und die kleinste Zahl ausgeben soll

Das Ziel:
- Die kleinste Zahl aller eingegebenen Zahlen soll am Ende per cout angezeigt werden
 

War-10-ck

střelec
Veteran

Registriert
14 Juli 2013
Beiträge
5.952
Ort
Schießstand
Nun gut, ich würde meinen dass man mit den Vorgaben nun ziemlich gut weiter überlegen kann. Schritt für Schritt denken was macht der User wie muss das Programm aufgebaut sein.

Wenn du dennoch möchtest, dass ich dir was Fertiges hinschreibe sag bescheid. Ich denke aber, dass es selbstgeschrieben den größten Lernfaktor hat. Verbessern kann man immer bei spezifischen Fragen.
 

MingsPing

NGBler

Registriert
15 Juli 2013
Beiträge
347
Hier ein paar Fakten, die dir helfen werden, deinen Fehler zu finden:
- Die Zahlen sollen positive ganze Zahlen sein (input >= 0)
- int min=0;
- if(input == 0) break;
- if (input<min) min=input;
Als Frage für dich: Wann (für welchen input) wird die Abfrage (input<min) wahr?

Edit: Mist, hatte War-10-ck's Beitrag nicht gesehen.

Also, Anwort: Für keinen Input wird die Abfrage wahr => min wird nie anders gesetzt (bleibt 0).
Workaround: definiere min so groß wie möglich.
Hier siehst du die Wertebereiche der einzelnen Typen:
http://msdn.microsoft.com/en-us/library/s3f49ktz(v=vs.80).aspx
 
Zuletzt bearbeitet:

Sp1xx

NGBler

Registriert
9 Okt. 2013
Beiträge
643
Ort
Bavaria
  • Thread Starter Thread Starter
  • #11
Vielen Dank für die Hilfestellung.

Nun klappt es.

aus
[src=cpp]int input[/src]

habe ich:

[src=cpp]unsigned int input;[/src]

gemacht, da der Wertebreich dort nur positiv sein kann ( 0 to 4,294,967,295 )


[src=cpp]int min=10000;[/src]

hier habe ich den Startwert von min möglichst hoch gesetzt. Mir wird jetzt erst klar das input nicht kleiner sein kann als 0 und deswegen wie du schon sagtest die if anwendung nie true werden konnte :m

Ich denke das hat mir für das Verständnis sehr geholfen!
 

MingsPing

NGBler

Registriert
15 Juli 2013
Beiträge
347
Was, wenn eine Person jetzt 10001 und 10002 eintippt und dann 0? Was wird ausgegeben?
 

Sp1xx

NGBler

Registriert
9 Okt. 2013
Beiträge
643
Ort
Bavaria
  • Thread Starter Thread Starter
  • #13
Dann wird 10000 ausgegeben da min diesen Wert am Anfang zugewiesen bekommen hat.

Da 10001 und 10002 größer als dieser Wert sind ändert sich dieser auch nicht.
 

War-10-ck

střelec
Veteran

Registriert
14 Juli 2013
Beiträge
5.952
Ort
Schießstand
Das ist aber ja nicht gewollt, schließlich hat der User 10000 nie eingegeben. Man könnte zum Beispiel den Nutzer auch am Anfang auffordern zuerst eine positive Ganzzahl einzugeben mit der gestartet werden soll. Schafft er das nicht wird ein Fehler statt einem Ergebnis zurückgegeben.
 

MingsPing

NGBler

Registriert
15 Juli 2013
Beiträge
347
Deshalb meinte ich, du sollst min so groß wie möglich setzen (also obere Grenze des Wertebereichs).

Wenn du Listen beherrscht, kannst du dein Programm (schöner) umgestalten, sodass es ohne diesen "Trick" mit dem größtmöglichen min auskommt.

(Nur so am Rande: Es gibt nämlich auch Programmiersprachen, wo Integer keine festen minmalen/maximalen Grenzen haben!)
 

BurnerR

Bot #0384479

Registriert
20 Juli 2013
Beiträge
5.507
Ich hoffe die Kommentare hast du nicht wegen mir hinzugeügt, so war das von mir nicht gemeint. Die Kommentare kannst du alle wieder rausnehmen, die sind irrelevant.
while(input>0) //solange input größer als 0 ist wird die Schleife ausgeführt
Im Kommentar steht das selbe wie im Quelltext. Nur kommentieren, wenn du etwas schreiben möchtest, was nicht unmittelbar aus dem Quelltext hervorgeht.

Ich meinte das umgekehrt, nicht dem quellcode eine natürlichsprachliche Beschreibung hinzufügen, sondern verbal aufschreiben was du machen willst. Und daraus dann den Quellcode bauen.

Workaround: definiere min so groß wie möglich.
Das ist keine gute Lösung. Davon solltest du Abstand nehmen.

Wenn du Listen beherrscht...
Listen wäre hier auch fehl am Platze, es soll nur eine einzelne Zahl ausgegeben werden und in der Funktion selber muss auch nur eine einzelne zwischen gespeichert werden, nämlich die aktuell kleinste.
 

Kugelfisch

Nerd

Registriert
12 Juli 2013
Beiträge
2.342
Ort
Im Ozean
In C++ würde sich der Wert
[src=cpp]numeric_limits<unsigned int>::max()[/src]
zur Initialisierung anbieten - der grösste Wert, welchen ein unsigned int aufnehmen kann. Dazu muss der Header <limits> inkludiert werden.

Alternativ sei eine elegante echte C++-Lösung unter Benutzung der Standardbibliothek genannt (verarbeitet auch negative Ganzzahlen - terminiert sich, sobald ein Buchstabe oder eine ungültige Zahl eingegeben wird):
[src=cpp]#include <iostream>
#include <iterator>
#include <algorithm>

int main() {
std::cout << *std::min_element(std::istream_iterator<int>(std::cin),std::istream_iterator<int>()) << std::endl;
}[/src]
 

accC

gesperrt

Registriert
14 Juli 2013
Beiträge
5.250
Pseudo-Code:

[src=cpp]int res=MAXINT; // in c++ #include <math.h>

while (true) {

lese x; // string

try {
int i = std::stoi(x); // convert to integer
} catch (Exception e) {
break; // not an int value => break loop
}

res = i < res ? i : res; // store new min

}

schreibe res; // min[/src]

Also zuerst mal initialisiere ich das Minimum mit dem maximal möglichen Wert (jeder Input sollte <= diesem Wert sein).
Damit kann ich selbst nach dem ersten Input valide das Minimum ausgeben. ;)

Dann starte ich eine "Endlos"schleife, in der ich..
eine neue Eingabe einlese
diese Eingabe versuche in Int umzuwandeln

gelingt die Umwandlung nicht (std::stoi sollte dann eine exception werfen), dann fange ich zunächst den Fehler und beende meine "Endlos"schleife

gelingt die Umwandlung, dann ist der umgewandelte Wert mein neuer potentieller Kandidat für das Minimum
ich vergleiche ihn also mit meinem zuletzt gespeicherten Minimum und speichere mir das neue Minimum aus den beiden Werten
 

Sp1xx

NGBler

Registriert
9 Okt. 2013
Beiträge
643
Ort
Bavaria
  • Thread Starter Thread Starter
  • #19
Hey,

danke für die ausführliche Erklärung.

Meine Umsetzung sieht so aus:

[src=cpp]#include <iostream>
#include <iomanip>
#include <math.h>

using namespace std;


int main()

{
int res=INT_MAX;
int x;


while (true) {

cout<<"Geben sie eine Zahl ein:";
cin>>x;

if(x<=0)
break;

if (x<res) res=x; // store new min

}

cout<<"die kleinste Zahl ist"<<res;


}[/src]

Dieser Version klappt auch ohne Probleme!

Diese Passage verstehe ich leider nicht:

Hier wird der input zu einem integer umgewandelt, Nachkommastellen also wegrationalisiert? Warum?

[src=cpp]int i = std::stoi(x); // convert to integer[/src]

Und hier wird geschaut ob die eingegebene Zahl ein integer Wert ist?


[src=cpp]} catch (Exception e) {
break; // not an int value => break loop[/src]

Also im Prinzip das gleiche wie ich mit dieser Zeile erreiche:

[src=cpp]if(x<=0)
break;
[/src]

Danke für eure Hilfe das hilft mir enorm!


//Edit: Ich merke gerade das bei negativen Zahlen eine große Random Zahl ausgegeben wird. Wahrscheinlich willst du das mit der Umwandlung in eine Integer Zahl verhindern?
 
Zuletzt bearbeitet:

epiphora

aus Plastik
Veteran

Registriert
14 Juli 2013
Beiträge
3.894
Ort
DE-CIX
[src=cpp]res = i < res ? i : res; // store new min[/src]

Das finde ich unnötig kompliziert, eine einfache Abfrage, ob der Wert kleiner ist und eine davon abhängige Zuweisung wäre besser. Anderenfalls wird res immer ein neuer Wert zugewiesen, der eben teilweise der alte res-Wert ist. Der Compiler würde das vermutlich ohnehin weg-optimieren, aber die Lesbarkeit vom Code wird dadurch unnötigerweise erschwert.

Außerdem enthält Dein Code eine falsche Abbruchbedingung. Das Programm soll ja nicht beendet werden, wenn eine nicht-numerische Eingabe erfolgt, sondern wenn die Eingabe 0 ist. Da in der Aufgabe ausnahmslos genannt wird, dass Zahlen eingegeben werden, könnte man sich die Abfrage nach dem String ohnehin sparen.
 
Oben