PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [C++] If schleife kaputt



keinWort
13-09-2005, 12:07
Ich habe ein ganz dummes Problem, welches das unten stehende "Programm" verdeutlichen soll. Bei meine Compiler (Dev-Cpp 4.9.9.2) passiert folgendes:

Das Programm läuft. Wenn ich die eins wähle wird der Zweig für die eins und der else Zweig ausgeführt (falsch), bei einer zwei nur der Zweig für die zwei (richtig).

Warum geht das nicht?



#include <cstdlib>
#include <iostream>

using namespace std;

int menue();
void wahl(int *);

int menue()
{
int a;
cout << "Wahl: ";
cin >> a;
return a;
}

void wahl(int *a)
{
if(*a==1){
cout << "eins: " << *a << endl;}
if(*a==2){
cout << "zwei: " << *a << endl;}
else{
cout << "was anderes " << *a;}
}

int main(int argc, char *argv[])
{
int z;
z=menue();
wahl(&z);
system("PAUSE");
return EXIT_SUCCESS;
}

Boron
13-09-2005, 12:29
void wahl(int *a)
{
if(*a==1){
cout << "eins: " << *a << endl;
}
else if(*a==2){
cout << "zwei: " << *a << endl;
}
else{
cout << "was anderes " << *a;
}
}

keinWort
13-09-2005, 12:33
In meinem C++ Handbuch (Erlenkoetter) steht es so wie ich es gepostet habe.

Aber deine lösung funktioniert.
Danke.


christian

Boron
13-09-2005, 12:51
Was du wolltest ist auch eine genau Unterscheidung zwischen den möglichen Eingaben.
Entweder ist es eine 1, oder eine 2 oder was ganz anderes.

Und das kann man mit dieser
if
else if
else if
...
else
Konstruktion machen.


Das Buch das du hast ist dann wohl an dieser Stelle einfach falsch (Druck/Schreibfehler; vermutlich unbasichtlich).

Dort wird halt zuerst geprüft ob die Eingabe eine 1 ist. Wenn ja erfolgt eine Ausgabe.
Anschließend beginnt ja eine komplett neue Anweisung: if ( *a==2 ) ... else ...

Da die Eingabe ja eine 1 ist ist die Bedingung im zweiten if falsch und das Programm führt konsequenterweise den else-Pfad aus (Ausgabe: "was anderes:").

keinWort
13-09-2005, 12:59
Wie eine if-Schleife funktioniert ist mir klar. Nur das ich die Syntax falsch im Kopf und im Buch hatte. Wie dem auch seit, dank dafür.

Es hing nur an der Schreibweise.

Christian

Joghurt
13-09-2005, 13:10
Zur verdeutlichung Was bei *a = 1 bei fehlendem else passiert, ist folgendes:


if (*a ==1) { ... } // wird ausgeführt
if (*a ==2) { ... } // nein, da *a != 2
else {...} // wird ausgeführt, da *a == 2 falsch war.

PS: Normalerweise benutzt man für sowas switch:

switch (*a) {
case 1: {
...;
break;
}
case 2: {
...;
break;
}
default: {
...;
}
}Die breaks sind wichtig, da case-Anweisungen sowas wie Labels sind (die {} um die jeweilige case-Anweisung ist nicht unbedingt notwendig, aber guter Stil)

bischi
13-09-2005, 13:12
Wie eine if-Schleife funktioniert ist mir klar.

Bist du da ganz sicher?! Ich hab nämlich noch nie von einer if-SCHLEIFE gehört - höchstens von ner if-Anweisung.

MfG Bischi

anda_skoa
13-09-2005, 13:29
Übrigens brauchst du mit Sicherheit kein int*

Selbst wenn du a in der Funktion ändert willst, würde ein int& reichen.

int* braucht man praktisch nur, wenn der Parameter optional ist

Ciao,
_

Ko_Onrad
16-09-2005, 21:07
int* braucht man praktisch nur, wenn der Parameter optional ist

Kannste das mal bitte genauer erläutern? Verstehe Ich nämlich nicht..

anda_skoa
16-09-2005, 21:31
Kannste das mal bitte genauer erläutern? Verstehe Ich nämlich nicht..

Wenn man nur einen int in eine Funktion hinein transportieren will


void foo(int a)
{
cout << a;
}


Wenn man einen int in einer Funktion bearbeiten will


void foo(int& a)
{
cout << a;
a++;
}


Wenn man einen int optional zur Verfügung stellen möchte


void foo(int* a = 0)
{
if (a != 0) *a = 5;
}


Letzteres kann man auch lösen, wenn man zwei foo() macht, eine mit und eine ohne int


int foo()
{
}
int foo(int& a)
{
a = 5;
}


Optional wird manchmal benutzt, wenn mehrere Parameter optional sind und es sonst zu viele einzelen Versionen werden, zb


bool parseXML(const string& xmlstring, string* error = 0, int* errorLine = 0, int* errorColumns = 0)

D.h. der Benutzer der Funktion kann bei Bedarf zwei int Pointer angeben und so eine genauere Information über einen Fehler und den Ort eines Fehlers erhalten.

Man könnte auch wie oben beschrieben folgendes machen


bool parseXML(const string& xmlstring);
bool parseXML(const string& xmlstring, string& error);
bool parseXML(const string& xmlstring, string& error, int& errorLine);
bool parseXML(const string& xmlstring, string& error, int& errorLine, int& errorColumns);

Wobei man dann natürlich die ersten drei als inline Wrapper um die vierte Funktion implementieren kann, also zB


bool parseXML(const string& xmlstring)
{
string error;
int line;
int col;

return parseXML(xmlstring, error, line, col);
}


Ciao,
_

Ko_Onrad
18-09-2005, 11:30
Ach, da wolltest du rauf hinaus. Sorry, das ich dich so viel schreiben lassen hab. Aber ich hab gedacht das du da irgendwas anderes meinst.
Ich hatte nämlich das hier im Hinterkopf, was ja auch geht, und weshalb ich ein wenig verwirrt war:


#include <iostream>

int add(int const & first, int const & second = int()) {
return first + second;
}

int main(int argc, char **argv) {
std::cout << add(5);
std::cout << add(5,5);
return 0;
}

Das Beispiel ist zwar relativ sinnlos, aber so geht's auch.

Joghurt
18-09-2005, 13:20
Das Beispiel zeigt aber nicht, warum Referenzen da sind; in deinem Beispiel sind sie sogar sinnfrei. Besser:

void add(int& x, int y)
{
x += y;
}
#include <iostream>
int main()
{
int x = 12;
add(x,9);
std::cout << x; // 21Oder, das Musterbeispiel swap
template <typename T>void swap(T& a, T& b)
{
T tmp = a;
a = b;
b = tmp;
}


int main()
{
int a,b;
std::string x,y;
a = 5; b = 2;
x = "Hallo"; y = "Welt";
swap(a,b); swap(x,y); // a = 2, x = "Welt"
}

Ko_Onrad
18-09-2005, 14:35
Hallo,


Das Beispiel zeigt aber nicht, warum Referenzen da sind; in deinem Beispiel sind sie sogar sinnfrei.
Ich habe doch geschrieben dass das Beispiel "relativ sinnlos" ist.
Und im übrigen wurde trotzdem ein Verwendungszweck aufgezeigt. Nämlich das Referenzen in einigen Fällen dem Copy Konstruktor vorzuziehen sind. In diesem Fall ist es egal, da ein int und eine Referenz gleich groß sind, wäre es im Beispiel aber kein int sondern eine Referenz auf ein "GroßeKlasse" Objekt würden wir durch die Verwendung von Referenzen Platz sparen.



Besser:

void add(int& x, int y)
{
x += y;
}

Ob das jetzt besser oder schöner ist, darüber kann man sich streiten..
Soll auch nicht das Thema sein, da das Beispiel, wie gesagt, sinnlos ist.