it-swarm.com.de

Gibt es in C eine eingebaute Swap-Funktion?

Gibt es in C eine eingebaute Swap-Funktion, die ohne Verwendung einer dritten Variablen funktioniert?

29
user1149207

Nein.
C++ hat aber es funktioniert wie c = a;a = b; b = c;
C++ integrierte Swap-Funktion: swap(first,second);
.__ Überprüfen Sie dies: http://www.cplusplus.com/reference/algorithm/swap/

Sie können dies verwenden, um zwei Variablenwerte auszutauschen, ohne die dritte Variable zu verwenden: 

a=a^b;
b=a^b;
a=b^a;

Sie können dies auch überprüfen:

https://stackoverflow.com/questions/756750/swap-the-values-of-to-variablen-ohne-verwendungsvariable

Wie tausche ich ohne dritte Variable aus?

24
Saif

Warum möchten Sie keine dritte Variable verwenden? Dies ist der schnellste Weg bei der überwiegenden Mehrheit der Architekturen.

Der Swap-Algorithmus XOR funktioniert ohne eine dritte Variable, ist jedoch auf zweierlei Weise problematisch:

  1. Die Variablen müssen eindeutig sein, d. H. swap(&a, &a) funktioniert nicht.
  2. Es ist im Allgemeinen langsamer.

Es kann manchmal vorzuziehen sein, den Swap XOR zu verwenden, wenn die Verwendung einer dritten Variablen dazu führen würde, dass der Stapel überläuft. In der Regel können Sie diesen Aufruf jedoch nicht durchführen.

Um Ihre Frage direkt zu beantworten, gibt es in Standard C keine Swap-Funktion, obwohl das Schreiben trivial wäre.

23
Peter Alexander

In Standard C gibt es keine solche Funktion.

(In C++ haben Sie std::swap() .)


Vielleicht kann ein Makro aus diese Frage für Sie nützlich sein.

8
Igor Oks

Angenommen, Sie wollen eineC-Lotion, keine C++ eine, könnten Sie es zu einem Makro machen, zumindest mit der GCC-Erweiterung, um es generisch genug zu haben, so etwas

 #define SWAP(x,y) do {   \ 
   typeof(x) _x = x;      \
   typeof(y) _y = y;      \
   x = _y;                \
   y = _x;                \
 } while(0)

hüten Sie sich vor Tricks wie Aufrufe swap(t[i++],i); Um dies zu vermeiden, verwenden Sie den Adressoperator &. Und Sie sollten besser eine temporäre verwenden (für ganze Zahlen gibt es einen bekannten und nutzlosen Trick mit exklusiv-oder).

PS: Ich verwende zwei lokale Variablen _x und _y (aber ich hätte auch nur eine lokale Variable verwenden können), um die Lesbarkeit zu verbessern und möglicherweise auch weitere Optimierungen vom Compiler aus zu ermöglichen.

Es gibt keine Standardfunktion in C, um zwei Variablen auszutauschen.

Ein Makro kann folgendermaßen geschrieben werden:

#define SWAP(T, a, b) do { T tmp = a; a = b; b = tmp; } while (0)

und das Makro kann folgendermaßen aufgerufen werden:

int a = 42;
int b = 2718;

SWAP(int, a, b);

Einige Lösungen zum Schreiben eines SWAP-Makros sollten vermieden werden:

#define SWAP(a, b) do { a = b + a; b = a - b; a = a - b; } while (0)

wenn Operanden signierte Typen sind, kann es zu einem Überlauf kommen, und ein signierter Überlauf ist undefiniertes Verhalten.

Eine Lösung, die versucht, die Lösung XOR wie folgt zu optimieren, sollte vermieden werden:

#define SWAP(a, b) (a ^= b ^= a ^=b)

a wird zweimal zwischen dem vorherigen und dem nächsten Sequenzpunkt geändert, verstößt also gegen die Sequenzpunktregeln und ist undefiniertes Verhalten.

6
ouah

Da Sie eine beliebige Objektdarstellung in ein unsigniertes Char-Array in C kopieren können, können Sie mit dem folgenden Makro zwei Objekte vertauschen:

#define SWAP(X,Y) \
    do { \
        unsigned char _buf[sizeof(*(X))]; \
        memmove(_buf, (X), sizeof(_buf)); \
        memmove((X),  (Y), sizeof(_buf)); \
        memmove((Y), _buf, sizeof(_buf)); \
    } while (0)

GCC wird dafür in manchen Fällen sogar optimalen Code generieren. Vielleicht behalten Sie Ihren Job aber nicht ...

2
u0b34a0f6ae

Es gibt keine eingebaute Swap-Funktion, aber Sie können dies versuchen

a = a ^ b;

b = a ^ b;

a = b ^ a;

1
Saif

Es gibt eine C++ - Bibliotheksfunktion. Es vertauscht die Werte von zwei Ganzzahlvariablen. Zum Beispiel Swap (x, y); tauscht die Werte der Variablen x und y aus. In ähnlicher Weise tauschen (mat [i] [j], mat [j] [i]); tauscht zwei Werte in der Matrixmatte aus, nämlich den Wert in Zeile i Spalte j und den Wert in Zeile j Spalte i.

1

Ich glaube, ich habe eine typunabhängige Funktion für den Austausch von zwei Werten in Standard C entwickelt, obwohl ich in der Sprache ziemlich neu bin, habe ich vielleicht etwas übersehen. Es verwendet den Swap-Algorithmus XOR, und ich bin mir sicher, dass es mehr optimiert werden könnte, aber es funktioniert, solange die beiden Werte auf die gleiche Anzahl von Bytes zeigen, die durch das dritte Argument angegeben wird:

void swapn(void *a, void *b, size_t n) {
    if (a == b) {
        return;
    }

    size_t i;
    char *x = (char *)a,
        *y = (char *)b;

    for (i = 0; i < n; i++) {
        *x ^= *y;
        *y ^= *x;
        *x ^= *y;
        x++;
        y++;
    }
}

Verwendungsbeispiel:

// swap two integers
int x = 5,
    y = 30;

printf("%d\t%d\n", x, y);

swapn(&x, &y, sizeof(int));

printf("%d\t%d\n\n", x, y);

// swap two floats
float a = 9.23f,
    b = 6.83f;

printf("%.2f\t%.2f\n", a, b);

swapn(&a, &b, sizeof(float));

printf("%.2f\t%.2f\n\n", a, b);

// swap two doubles
double p = 4.7539,
    q = 0.9841;

printf("%.4f\t%.4f\n", p, q);

swapn(&p, &q, sizeof(double));

printf("%.4f\t%.4f\n\n", p, q);

// swap two chars
char m = 'M',
    n = 'n';

printf("%c\t%c\n", m, n);

swapn(&m, &n, sizeof(char));

printf("%c\t%c\n\n", m, n);

// swap two strings of equivalent length
char s[] = "Hello",
    t[] = "World";

printf("%s\t%s\n", s, t);

swapn(s, t, sizeof(s));

printf("%s\t%s\n\n", s, t);

Die Ausgabe ist:

5   30
30  5

9.23    6.83
6.83    9.23

4.7539  0.9841
0.9841  4.7539

M   n
n   M

Hello   World
World   Hello
0
Patrick Roberts
#define swap(T, x, y) \
    {                 \
        T tmp = x;    \
        x = y;        \
        y = tmp;      \
    }

int main()
{
    int a = 10;
    int b = 20;
    printf("a=%d b=%d\n", a, b);
    swap(int, a, b);
    printf("a=%d b=%d\n", a, b);

    return 0;
}
0
Li Kui

es gibt std::swap, da es in der Regel von Ihrem Prozessor abhängt, ob er das Tauschen unterstützt. Es gibt eine Anweisung namens "Compare and Swap", die jedoch nur für Typen funktioniert, die in ein Register passen, und ist garantiert atomar. Es gibt eine integrierte Implementierung von Compare und Swap (CAS) aus gcc , die für die Synchronisierung von Thread- und Mutex-Implementierungen verwendet wird und wahrscheinlich für Ihren Zweck nicht geeignet ist Wenn Sie wirklich an C hängen bleiben, können Sie immer ein Makro wie folgt verwenden:

#define swap(a,b) a=a^b; \
                  b=a^b; \
                  a=b^a;
0
Alex