[C++] Inhalte von zwei Variablen durch eine Funktion vertauschen

albaum

Ensign
Registriert
Juli 2014
Beiträge
172
Hallo,


ich wollte durch die Funktion swapIt die Variablen x und y miteinander vertauschen aber irgendwie funktioniert es nicht und ich finde den Fehler auch nicht...


Ich hoffe ihr könnt mir helfen. Dies ist der Quelltext den ich geschrieben habe:



#include <iostream>

using namespace std;

void swapIt(int x, int y)
{
int temp;
temp = x;
x = y;
y = temp;
}

int main()
{
int x=5;
int y=10;

cout << "Vorher: x= "<< x << " y = " << y << endl;

swapIt (x,y);

cout << "Nachher: x= "<< x << " y = " << y << endl;

return 0;
}
 
Hey,

1. Bitte Code in entsprechende Code-Tags einbetten.

2. Du verwendest call-by-value statt call-by-reference -> LINK

In aller Kürze: du vertauschst die beiden Variablen zwar, aber nur innerhalb der Funktion, ohne Referenz wird dieser Tausch nicht nach außen getragen bzw auf die übergebenen Variablen selbst angewendet.
 
Ist doch klar was Du falsch machst. Deine Funktionsparameter sind eine Kopie! der Übergabe. Dann kannst Du lange die Werte in der Funktion ändern, es bleibt ohne Auswirkung im main(). Die Übergabeparameter müssen by Reference übergeben werden, wenn Deine Routine die verändern soll und anschließend im main() die neuen Werte haben sollen.

Das sieht dann so aus:
void swapIt(int &x, int &y)
{
...

Das & ist der Operator für die Übergabe als Referenz, quasi das Gegenstück zum Pointer in C nur eleganter.

Viel Erfolg.
 
Servus albaum, so müsste es aussehen.


Code:
#include <stdio.h> 
#include <stdlib.h> 
  
int swapInt (int zahl1, int zahl2)  
{ 
    int temp; 
    temp = zahl1; 
    zahl1 = zahl2; 
    zahl2 = temp;   
        
    return zahl1, zahl2;
}
  
int main() 
{ 
    int zahl1, zahl2; 
    printf("Bitte 2 Zahlen eingeben: \n"); 
    
    scanf("%d", &zahl1); 
    fflush(stdin); 
    scanf("%d", &zahl2); 
    
    printf("zahl1 lautet: %d\n zahl2 lautet: %d\n", zahl1, zahl2); 
    printf("zahl1 lautet: %d\n zahl2 lautet: %d\n", swapInt(zahl1, zahl2)); 
    
    
    system; 
    return 0;   
}
 
Zuletzt bearbeitet:
@Hexxxer76

Im Main sind die Zahlen dadurch aber noch nicht getauscht worden.
 
Die STL enthält übrigens eine Funktion die dies erledigen kann.
http://en.cppreference.com/w/cpp/algorithm/swap
Code:
#include <iostream>
#include <utility> //Falls nicht C++11 unterstützt wird <algorithm> verwenden

int main()
{
    int x = 5;
    int y = 10;
    std::cout << "Vorher: x= "<< x << " y = " << y << std::endl;
    std::swap(x, y);
    std::cout << "Nachher: x= "<< x << " y = " << y << std::endl;
    return 0;
}

Und als Hinweis noch. Verwende am besten niemals "using namespace std". Früher oder später kann einem das irgend wann mal auf die Füße fallen. ;)

@Hexxxer76
Ja, in C würde man so Sachen wie scanf oder printf verwenden, aber bitte nicht in C++ :rolleyes:
 
Hexxxer76 schrieb:
Servus albaum, so müsste es aussehen.


Code:
#include <stdio.h> 
#include <stdlib.h> 
  
int swapInt (int zahl1, int zahl2)  
{ 
    int temp; 
    temp = zahl1; 
    zahl1 = zahl2; 
    zahl2 = temp;   
        
    return zahl1, zahl2;
}
  
int main() 
{ 
    int zahl1, zahl2; 
    printf("Bitte 2 Zahlen eingeben: \n"); 
    
    scanf("%d", &zahl1); 
    fflush(stdin); 
    scanf("%d", &zahl2); 
    
    printf("zahl1 lautet: %d\n zahl2 lautet: %d\n", zahl1, zahl2); 
    printf("zahl1 lautet: %d\n zahl2 lautet: %d\n", swapInt(zahl1, zahl2)); 
    
    
    system; 
    return 0;   
}

Nicht so richtig. Das return zahl1, zahl2; tut etwas völlig anderes, als Du glaubst. Du nutzt hier den Komma-Operator. Der wertet erst den Ausdruck vor dem Komma aus, wertet dann den Ausdruck nach dem Komma aus und gibt den Wert des Ausdrucks nach dem Komma zurück. Das Verwenden des Komma-Operators führt nicht dazu, dass (wie Du anscheinend glaubst) plötzlich 2 Dinge aus einer Funktion zurückgeben kannst.
 
Lösung:

Code:
void swapp ( int *a, int *b ) {
    int *c=*a;
    *a=*b;
    *b=c;
}

void main () {

int zahl1=1,
    zahl2=2;

swapp ( &zahl1, &zahl2 );
printf ("a=%d b=%d\n",zahl1,zahl2);
// Ausgabe : 2,1
}
 
Ich würde keine Pointer usen, dann muss man eigentlich noch auf nullptr etc checken.

Code:
void swap(int& a, int& b) {
    int temp = a;
    a = b;
    b = temp;
}

int main(int argc, char const *argv[])
{
    int a = 1337, b = 6077;
    swap( a, b );
    printf("a=%i b=%i", a, b);
    return 0;
}

Da es im Übrigen um C++ geht kannst du auch die STD usen:

Code:
#include <algorithm>
#include <iostream>
 
int main()
{
   int a = 5, b = 3;
 
   // before
   std::cout << a << ' ' << b << '\n';
 
   std::swap(a,b);
 
   // after
   std::cout << a << ' ' << b << '\n';
}
 
Code:
int temp;
temp = x;

Uff, bitte nicht. Das findet schon in C89 keiner mehr toll und in C++ funktioniert diese Art der Deklaration häufig nicht. Gewöhne dir diesen Stil am besten gar nicht erst an und initialisiere die Variablen direkt:

Code:
int temp = x;
 
Bitteschön:
Code:
class A {
public:
  A(int x) : _x(x) { }
private:
  int _x;
};

A a; // Error

Und selbst wenn die Klasse einen Standardkonstruktor hat, ist es besonders bei aufwändigeren Klassen Ressourcenverschwendung, da ja folgendes passiert:
Code:
A a; // Standardkonstruktor wird aufgerufen
a = A(6); // Konstruktor erzeugt anonymes Objekt, danach Aufruf von Move-Assignment-Operator, zuletzt Destruktor für anonymes Objekt

vs.
Code:
A a(6); // Konstruktor wird aufgerufen
 
Zuletzt bearbeitet:
Das spielt für die Basistypen aber keine Rolle.
 
Das ist richtig, aber warum für Basistypen die objektiv schlechtere und meiner Meinung nach auch nicht besonders lesbare Variante wählen, wenn die andere immer (insbesondere auch bei Templates!) funktioniert?
 
Zurück
Oben