Scambiare il valore di due variabili senza utilizzare la terza variabile


104

Una delle domande molto difficili poste in un'intervista.

Scambia i valori di due variabili come a=10e b=15.

Generalmente per scambiare due valori di variabili, abbiamo bisogno di una terza variabile come:

temp=a;
a=b;
b=temp;

Ora il requisito è scambiare i valori di due variabili senza utilizzare la terza variabile.


76
Wow. Una domanda dell'intervista scelta male IMHO. Questa è una tecnica che raramente, se non mai, utile nella pratica. Ci sono buone probabilità che confonda solo l'ottimizzatore del compilatore risultando in un codice meno efficiente di uno "scambio temporaneo". A meno che questo posto in cui stavi intervistando non sia coinvolto in cose molto matematiche (pensa: sviluppo di algoritmi di crittografia o simili) non riesco a immaginare una buona ragione per porre una domanda del genere.
Dan Molding

10
In effetti, quella domanda non ti dice altro che se il candidato conosce questo particolare trucco che è praticamente inutile nel codice di produzione. Suppongo che potresti imbatterti nel mago occasionale che lo capisce al volo, ma è probabile che persone del genere che non conoscono già il trucco siano piuttosto rare.
CEO

2
Forse vogliono eliminare le persone che pensano che conoscere questi trucchi sia ciò che rende un buon programmatore? Inoltre, quando si legge dello xor-trick, prestare attenzione a quando fallirà (il che IMO lo rende praticamente completamente inutile per lo scambio di interi per scopi generali).
UncleBens

Risposte:


155

Utilizzando l' algoritmo di scambio xor

void xorSwap (int* x, int* y) {
    if (x != y) { //ensure that memory locations are different
       *x ^= *y;
       *y ^= *x;
       *x ^= *y;
    }
}


Perché il test?

Il test è garantire che x e y abbiano posizioni di memoria diverse (anziché valori diversi). Questo perché (p xor p) = 0e se sia x che y condividono la stessa posizione di memoria, quando uno è impostato a 0, entrambi sono impostati a 0. Quando sia * x che * y sono 0, tutte le altre operazioni xor su * xe * y saranno uguali 0 (poiché sono uguali), il che significa che la funzione imposterà sia * x che * y a 0.

Se hanno gli stessi valori ma non la stessa posizione di memoria, tutto funziona come previsto

*x = 0011
*y = 0011
//Note, x and y do not share an address. x != y

*x = *x xor *y  //*x = 0011 xor 0011
//So *x is 0000

*y = *x xor *y  //*y = 0000 xor 0011
//So *y is 0011

*x = *x xor *y  //*x = 0000 xor 0011
//So *x is 0011


Questo dovrebbe essere usato?

In casi generali, no. Il compilatore ottimizzerà la variabile temporanea e dato che lo scambio è una procedura comune, dovrebbe produrre il codice macchina ottimale per la tua piattaforma.

Prendiamo ad esempio questo programma di test rapido scritto in C.

#include <stdlib.h>
#include <math.h>

#define USE_XOR 

void xorSwap(int* x, int *y){
    if ( x != y ){
        *x ^= *y;
        *y ^= *x;
        *x ^= *y;
    }
}

void tempSwap(int* x, int* y){
    int t;
    t = *y;
    *y = *x;
    *x = t;
}


int main(int argc, char* argv[]){
    int x = 4;
    int y = 5;
    int z = pow(2,28); 
    while ( z-- ){
#       ifdef USE_XOR
            xorSwap(&x,&y);
#       else
            tempSwap(&x, &y);
#       endif
    }
    return x + y;    
}

Compilato utilizzando:

gcc -Os main.c -o swap

La versione xor accetta

real    0m2.068s
user    0m2.048s
sys  0m0.000s

Dove come la versione con la variabile temporanea prende:

real    0m0.543s
user    0m0.540s
sys  0m0.000s

1
Potrebbe valere la pena spiegare il perché del test (cioè che l'approccio triplo xor fallisce orribilmente se xey fanno riferimento allo stesso oggetto).
dmckee --- gattino ex moderatore

1
Non so come questo abbia ottenuto così tanti voti positivi quando il codice è così rotto. Entrambi gli scambi nel segmento di codice testato sono completamente errati. Guarda da vicino.
SoapBox

@ SoapBox: ottimo punto! Lo scambio XOR azzera x & lascia y intatto, e lo scambio temporaneo lascia entrambi con il valore di x. Ops!
Drew Hall

4
@ SoapBox Buona cattura. Risolto e ritestato e non ho riscontrato alcuna differenza sostanziale nei tempi.
Yacoby

4
L'interrogante ha detto due variabili, non int. : P
Plumenator

93

la forma generale è:

A = A operation B
B = A inverse-operation B
A = A inverse-operation B 

tuttavia devi potenzialmente fare attenzione agli overflow e inoltre non tutte le operazioni hanno un inverso che è ben definito per tutti i valori che l'operazione è definita. es. * e / funzionano finché A o B è 0

xor è particolarmente piacevole in quanto è definito per tutti gli interi ed è il suo inverso


XOR (X, X) == 0, quindi xor funziona per int TRANNE quando i due valori scambiati sono uguali. Non sono il primo a farlo notare e troppi l'hanno detto (qui e altrove) per individuare qualcuno per il merito.
AlanK,

85
a = a + b
b = a - b // b = a
a = a - b

16
E se a+btrabocca?
Alok Singhal

2
@Alok: Questo non viene preso in considerazione, quindi non è pratico :)
Dor

4
Se a e b sono degli stessi, tipi interi di base, di dimensioni (come int, unsigned short, ...), funziona ancora fuori, alla fine, anche con troppopieno, perché se a + b trabocca, poi a - b sarà underflow. Con questi tipi interi di base, i valori si limitano al rollover.
Patrick Johnmeyer

10
In C, l'uso di questo su unsignedtipi interi va bene e funziona sempre. Sui tipi firmati, invoca un comportamento non definito in caso di overflow.
jpalecek

1
@ Shahbaz: anche se gli interi con segno sono archiviati nel complemento a 2, il comportamento in caso di overflow è ancora indefinito.
Keith Thompson

79

Nessuno ha ancora suggerito di usarlo std::swap.

std::swap(a, b);

Io non uso le variabili temporanee e in funzione del tipo di ae bla realizzazione può avere uno specalization che non lo fa neanche. L'implementazione dovrebbe essere scritta sapendo se un "trucco" è appropriato o meno. Non ha senso provare a indovinare.

Più in generale, probabilmente vorrei fare qualcosa di simile, poiché funzionerebbe per i tipi di classe che consentono ad ADL di trovare un sovraccarico migliore, se possibile.

using std::swap;
swap(a, b);

Naturalmente, la reazione dell'intervistatore a questa risposta potrebbe dire molto sul posto vacante.


ovviamente in C ++ 0x swap userà riferimenti rvalue quindi sarà ancora meglio!
jk.

16
Tutti vogliono mostrare il brillante xor o altro trucco che hanno imparato, con vari avvertimenti su come usarlo, ma questa è senza dubbio la risposta migliore.

2
perché non std :: swap (a, b); ? Voglio dire, perché l'uso?
Dinaiz

2
@Dinaiz senza le implementazioni std::definite swapdall'utente per i tipi definiti dall'utente sono anche disponibili per la chiamata (questo è ciò che si intende con "funzionerebbe per i tipi di classe consentendo ad ADL di trovare un sovraccarico migliore, se possibile").
Kyle Strand

std::swaputilizza memoria temporanea aggiuntiva nella sua implementazione no? cplusplus.com/reference/utility/swap
Ninja

19

Come già notato da manu, l'algoritmo XOR è popolare che funziona per tutti i valori interi (che include i puntatori quindi, con un po 'di fortuna e casting). Per completezza vorrei menzionare un altro algoritmo meno potente con addizione / sottrazione:

A = A + B
B = A - B
A = A - B

Qui devi stare attento agli overflow / underflow, ma per il resto funziona altrettanto bene. Potresti anche provarlo su float / double nel caso in cui XOR non sia consentito su quelli.


" tutti i valori interi (che include i puntatori quindi) " - Cosa? No, i puntatori non sono numeri interi e non è possibile xor valori del puntatore. Inoltre, non puoi xor valori a virgola mobile. Tuttavia, il metodo di addizione / sottrazione ha un comportamento indefinito (per i tipi con segno o virgola mobile) su overflow o underflow, può perdere la precisione per il virgola mobile e non può essere applicato a puntatori o altri tipi non numerici.
Keith Thompson

@ KeithThompson - OK, la perdita di precisione per i punti mobili è vera, ma a seconda delle circostanze, potrebbe essere accettabile. Per quanto riguarda i puntatori, beh, non ho mai sentito parlare di un compilatore / piattaforma in cui i puntatori non possono essere espressi liberamente su numeri interi e viceversa (facendo attenzione a scegliere un numero intero della giusta dimensione, ovviamente). Ma poi, non sono un esperto di C / C ++. So che va contro lo standard, ma avevo l'impressione che questo comportamento fosse abbastanza coerente in ... tutto.
Vilx-

1
@ Vilx-: Perché sarebbe accettabile una perdita di precisione quando è così facile evitarla utilizzando una variabile temporanea - o std::swap()? Certo, puoi convertire i puntatori in numeri interi e viceversa (supponendo che ci sia un tipo intero abbastanza grande, che non è garantito), ma non è quello che hai suggerito; hai sottinteso che i puntatori sono numeri interi, non che possono essere convertiti in numeri interi. Sì, la risposta accettata non funzionerà per i puntatori. La risposta di Charles Bailey usando std::swapè davvero l'unica corretta.
Keith Thompson

1
Prima di tutto, la domanda era "come scambiare senza usare una terza variabile" e il motivo addotto era "una domanda di intervista". Ho solo dato un'altra possibile risposta. Secondo, OK, mi scuso per aver insinuato che i puntatori siano numeri interi. Ho aggiornato la risposta per essere, si spera, più esplicita e corretta. Per favore correggimi se ho ancora torto (o aggiorna tu stesso la risposta). Terzo, ho cancellato la parte sulla risposta accettata. Non sta usando cast da puntatore a intero e funziona correttamente (per quanto ho capito).
Vilx-

@KeithThompson: La domanda potrebbe essere modificata per essere su come std::swappuò essere implementata senza utilizzare una terza variabile.
jxh

10

Le domande stupide meritano risposte appropriate:

void sw2ap(int& a, int& b) {
  register int temp = a; // !
  a = b;
  b = temp;
}

L'unico buon uso della registerparola chiave.


1
Un oggetto dichiarato con il registro della classe di archiviazione non è una "variabile"? Inoltre non sono convinto che questo sia un buon uso del registro, dal momento che se il tuo compilatore non è già in grado di ottimizzarlo, allora qual è il punto di provare, dovresti o accettare qualsiasi spazzatura che ottieni o scrivere l'assembly da solo ;-) Ma come dici, una domanda ambigua merita una risposta ambigua.
Steve Jessop

1
Praticamente tutti i compilatori moderni ignorano la classe di archiviazione dei registri, poiché hanno un'idea molto migliore di ciò che viene utilizzato di frequente rispetto a te.
CEO

6
Nota che questa risposta è destinata alle interviste, non ai compilatori. Sfrutta soprattutto il fatto che il tipo di intervistatori che fanno questo tipo di domande non capiscono veramente il C ++. Quindi, non possono rifiutare questa risposta. (e non esiste una risposta standard; ISO C ++ parla di oggetti non di variabili).
MSalters

Ah, ti capisco. Stavo cercando nello standard C la menzione della variabile come nome e non solo il significato non-const. Ne ho trovato uno in n1124, nella sezione sui cicli for che definiscono l'ambito delle "variabili" dichiarate nell'inizializzatore. Poi ho capito che la domanda era C ++ e non mi sono preoccupato di cercare per vedere se C ++ avesse fatto lo stesso errore di battitura ovunque.
Steve Jessop

3

Scambiare due numeri usando la terza variabile in questo modo,

int temp;
int a=10;
int b=20;
temp = a;
a = b;
b = temp;
printf ("Value of a", %a);
printf ("Value of b", %b);

Scambiare due numeri senza utilizzare la terza variabile

int a = 10;
int b = 20;
a = a+b;
b = a-b;
a = a-b;
printf ("value of a=", %a);
printf ("value of b=", %b);

2
#include<iostream.h>
#include<conio.h>
void main()
{
int a,b;
clrscr();
cout<<"\n==========Vikas==========";
cout<<"\n\nEnter the two no=:";
cin>>a>>b;
cout<<"\na"<<a<<"\nb"<<b;
a=a+b;
b=a-b;
a=a-b;

cout<<"\n\na="<<a<<"\nb="<<b;
getch();
}

1
Dopo che cout << "Enter the two no=:"mi aspettavo di leggerecout << "Now enter the two no in reverse order:"
user253751

Come con molte altre risposte, questo ha un comportamento indefinito se a+bo a-btrabocca. Inoltre, void main()non è valido e <conio.h>non è standard.
Keith Thompson

2

Poiché la soluzione originale è:

temp = x; y = x; x = temp;

Puoi renderlo un due linee usando:

temp = x; y = y + temp -(x=y);

Quindi rendilo un rivestimento usando:

x = x + y -(y=x);

1
Comportamento indefinito. yviene letto e scritto nella stessa espressione senza alcun punto di sequenza intermedio.
Keith Thompson

1

Se modifichi un po 'la domanda per chiedere circa 2 registri di assembly invece delle variabili, puoi anche usare l' xchgoperazione come un'opzione e l'operazione sullo stack come un'altra.


1
A quale xchgoperazione ti riferisci? La domanda non specificava un'architettura della CPU.
Keith Thompson

1

Considerate a=10, b=15:

Utilizzo di addizioni e sottrazioni

a = a + b //a=25
b = a - b //b=10
a = a - b //a=15

Utilizzo della divisione e della moltiplicazione

a = a * b //a=150
b = a / b //b=10
a = a / b //a=15

1
Ha un comportamento indefinito in caso di overflow.
Keith Thompson

1
Inoltre, in C ++, potrebbe avere un comportamento indesiderato quando i valori non sono dello stesso tipo. Ad esempio, a=10e b=1.5.
Matthew Cole

1
#include <iostream>
using namespace std;
int main(void)
{   
 int a,b;
 cout<<"Enter a integer" <<endl;
 cin>>a;
 cout<<"\n Enter b integer"<<endl;
 cin>>b;

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

  cout<<" a= "<<a <<"   b="<<b<<endl;
  return 0;
}

Aggiornamento: in questo stiamo prendendo l'input di due numeri interi dall'utente. Quindi stiamo usando l' XOR bit per bit operazione per scambiarli.

Supponiamo di avere due numeri interi a=4e b=9quindi:

a=a^b --> 13=4^9 
b=a^b --> 4=13^9 
a=a^b --> 9=13^9

Aggiungi una breve spiegazione alla tua risposta per i futuri visitatori.
Nikolay Mihaylov

1
In questo stiamo prendendo l'input di due numeri interi dall'utente. Quindi stiamo usando l'operazione xor bit per bit due scambiali. Supponiamo di avere due intergers a = 4 eb = 9 allora ora a = a ^ b -> 13 = 4 ^ 9 b = a ^ b -> 4 = 13 ^ 9 a = a ^ b -> 9 = 13 ^ 9
Naeem Ul Hassan,

1

Ecco un'altra soluzione ma un unico rischio.

codice:

#include <iostream>
#include <conio.h>
void main()
{

int a =10 , b =45;
*(&a+1 ) = a;
a =b;
b =*(&a +1);
}

qualsiasi valore nella posizione a + 1 verrà sovrascritto.


2
È stata una risposta utile, forse il valore è svanito.
Bibi Tahira,

1
Diversi tipi di comportamento indefinito. *(&a+1)potrebbe essere b. void main()è invalido. <conio.h>non è standard (e non lo usi nemmeno).
Keith Thompson

Il codice è stato testato con altri parametri di output, che hanno escluso, come ho detto, un rischio. Rischio di sovrascrivere la memoria .. Ecco lì .. Ma è stato utile scambiare due variabili senza il coinvolgimento della terza.
DareDevil

La parte peggiore è che potrebbe effettivamente funzionare alcune volte, quindi potresti non
rendertene

1

Ovviamente, la risposta in C ++ dovrebbe essere std::swap.

Tuttavia, non esiste nemmeno una terza variabile nella seguente implementazione di swap:

template <typename T>
void swap (T &a, T &b) {
    std::pair<T &, T &>(a, b) = std::make_pair(b, a);
}

Oppure, come one-liner:

std::make_pair(std::ref(a), std::ref(b)) = std::make_pair(b, a);

0
#include <stdio.h>

int main()
{
    int a, b;
    printf("Enter A :");
    scanf("%d",&a);
    printf("Enter B :");
    scanf("%d",&b);
    a ^= b;
    b ^= a;
    a ^= b;
    printf("\nValue of A=%d B=%d ",a,b);
    return 1;
}

0

questo è l'algoritmo di scambio XOR corretto

void xorSwap (int* x, int* y) {
   if (x != y) { //ensure that memory locations are different
      if (*x != *y) { //ensure that values are different
         *x ^= *y;
         *y ^= *x;
         *x ^= *y;
      }
   }
}

devi assicurarti che le posizioni di memoria siano diverse e anche che i valori effettivi siano diversi perché A XOR A = 0


Non devi assicurarti che i valori siano diversi.
user253751

0

Puoi farlo ... in modo semplice ... all'interno di una riga Logica

#include <stdio.h>

int main()
{
    int a, b;
    printf("Enter A :");
    scanf("%d",&a);
    printf("Enter B :");
    scanf("%d",&b);
    int a = 1,b = 2;
    a=a^b^(b=a);
    printf("\nValue of A=%d B=%d ",a,b);

    return 1;
}

o

#include <stdio.h>

int main()
{
    int a, b;
    printf("Enter A :");
    scanf("%d",&a);
    printf("Enter B :");
    scanf("%d",&b);
    int a = 1,b = 2;
    a=a+b-(b=a);
    printf("\nValue of A=%d B=%d ",a,b);

    return 1;
}

1
Comportamento indefinito. In entrambe le versioni, bviene letto e modificato all'interno della stessa espressione, senza alcun punto di sequenza intermedio.
Keith Thompson

0
public void swapnumber(int a,int b){
    a = a+b-(b=a);
    System.out.println("a = "+a +" b= "+b);
}

0

La risposta migliore sarebbe usare XOR e usarlo in una riga sarebbe fantastico.

    (x ^= y), (y ^= x), (x ^= y);

x, y sono variabili e la virgola tra di esse introduce i punti della sequenza in modo che non diventi dipendente dal compilatore. Saluti!


0

Vediamo un semplice esempio di c per scambiare due numeri senza usare la terza variabile.

programma 1:

#include<stdio.h>
#include<conio.h>
main()
{
int a=10, b=20;
clrscr();
printf("Before swap a=%d b=%d",a,b);
a=a+b;//a=30 (10+20)
b=a-b;//b=10 (30-20)
a=a-b;//a=20 (30-10)
printf("\nAfter swap a=%d b=%d",a,b);
getch();
}

Produzione:

Prima dello scambio a = 10 b = 20 Dopo lo scambio a = 20 b = 10

Programma 2: utilizzo di * e /

Vediamo un altro esempio per scambiare due numeri usando * e /.

#include<stdio.h>
#include<conio.h>
main()
{
int a=10, b=20;
clrscr();
printf("Before swap a=%d b=%d",a,b);
a=a*b;//a=200 (10*20)
b=a/b;//b=10 (200/20)
a=a/b;//a=20 (200/10)
printf("\nAfter swap a=%d b=%d",a,b);
getch();
}

Produzione:

Prima dello scambio a = 10 b = 20 Dopo lo scambio a = 20 b = 10

Programma 3: utilizzo dell'operatore XOR bit per bit:

L'operatore XOR bit per bit può essere utilizzato per scambiare due variabili. Lo XOR di due numeri xey restituisce un numero che ha tutti i bit come 1 ogni volta che i bit di xey differiscono. Ad esempio, XOR di 10 (in binario 1010) e 5 (in binario 0101) è 1111 e XOR di 7 (0111) e 5 (0101) è (0010).

#include <stdio.h>
int main()
{
 int x = 10, y = 5;
 // Code to swap 'x' (1010) and 'y' (0101)
 x = x ^ y;  // x now becomes 15 (1111)
 y = x ^ y;  // y becomes 10 (1010)
 x = x ^ y;  // x becomes 5 (0101)
 printf("After Swapping: x = %d, y = %d", x, y);
 return 0;

Produzione:

Dopo lo scambio: x = 5, y = 10

Programma 4:

Nessuno ha ancora suggerito di usare std :: swap.

std::swap(a, b);

Non uso variabili temporanee e, a seconda del tipo di aeb, l'implementazione potrebbe avere una specializzazione che non ne ha neanche uno. L'implementazione dovrebbe essere scritta sapendo se un "trucco" è appropriato o meno.

Problemi con i metodi sopra:

1) L'approccio basato sulla moltiplicazione e sulla divisione non funziona se uno dei numeri è 0 poiché il prodotto diventa 0 indipendentemente dall'altro numero.

2) Entrambe le soluzioni aritmetiche possono causare un overflow aritmetico. Se xey sono troppo grandi, l'addizione e la moltiplicazione potrebbero non rientrare nell'intervallo di numeri interi.

3) Quando usiamo puntatori a una variabile e facciamo uno scambio di funzione, tutti i metodi precedenti falliscono quando entrambi i puntatori puntano alla stessa variabile. Diamo un'occhiata a cosa succederà in questo caso se entrambi puntano alla stessa variabile.

// Metodo basato su XOR bit per bit

x = x ^ x; // x becomes 0
x = x ^ x; // x remains 0
x = x ^ x; // x remains 0

// Metodo basato su aritmetica

x = x + x; // x becomes 2x
x = x  x; // x becomes 0
x = x  x; // x remains 0

Vediamo il seguente programma.

#include <stdio.h>
void swap(int *xp, int *yp)
{
    *xp = *xp ^ *yp;
    *yp = *xp ^ *yp;
    *xp = *xp ^ *yp;
}

int main()
{
  int x = 10;
  swap(&x, &x);
  printf("After swap(&x, &x): x = %d", x);
  return 0;
}

Uscita :

Dopo lo scambio (& x, & x): x = 0

Lo scambio di una variabile con se stessa può essere necessario in molti algoritmi standard. Ad esempio, guarda questa implementazione di QuickSort dove possiamo scambiare una variabile con se stessa. Il problema di cui sopra può essere evitato ponendo una condizione prima dello scambio.

#include <stdio.h>
void swap(int *xp, int *yp)
{
    if (xp == yp) // Check if the two addresses are same
      return;
    *xp = *xp + *yp;
    *yp = *xp - *yp;
    *xp = *xp - *yp;
}
int main()
{
  int x = 10;
  swap(&x, &x);
  printf("After swap(&x, &x): x = %d", x);
  return 0;
}

Uscita :

Dopo lo scambio (& x, & x): x = 10


0

Forse fuori tema, ma se sai cosa stai scambiando una singola variabile tra due valori diversi, potresti essere in grado di eseguire la logica degli array. Ogni volta che viene eseguita questa riga di codice, il valore verrà scambiato tra 1 e 2.

n = [2, 1][n - 1]

0

Potresti fare:

std::tie(x, y) = std::make_pair(y, x);

Oppure usa make_tuple quando scambi più di due variabili:

std::tie(x, y, z) = std::make_tuple(y, z, x);

Ma non sono sicuro se internamente std :: tie utilizzi una variabile temporanea o meno!


0

In javascript:

function swapInPlace(obj) {
    obj.x ^= obj.y
    obj.y ^= obj.x
    obj.x ^= obj.y
}

function swap(obj) {
    let temp = obj.x
    obj.x = obj.y
    obj.y = temp
}

Sii consapevole del tempo di esecuzione di entrambe le opzioni.

Eseguendo questo codice l'ho misurato.

console.time('swapInPlace')
swapInPlace({x:1, y:2})
console.timeEnd('swapInPlace') // swapInPlace: 0.056884765625ms

console.time('swap')
swap({x:3, y:6})
console.timeEnd('swap')        // swap: 0.01416015625ms

Come puoi vedere (e come molti hanno detto), lo scambio sul posto (xor) richiede molto tempo rispetto all'altra opzione che utilizza la variabile temp.


0

R manca di un incarico concorrente come proposto da Edsger W. Dijkstra in A Discipline of Programming , 1976, cap.4, p.29. Ciò consentirebbe una soluzione elegante:

a, b    <- b, a         # swap
a, b, c <- c, a, b      # rotate right

-1
a = a + b - (b=a);

È molto semplice, ma potrebbe generare un avviso.


5
L'avvertimento è che non funziona? Non sappiamo se b=aviene eseguito prima o dopo a + b.
Bo Persson

-1

soluzione a riga singola per scambiare due valori in linguaggio c.

a=(b=(a=a+b,a-b),a-b);

Comportamento indefinito in caso di overflow.
Keith Thompson

-1
second_value -= first_value;
first_value +=  second_value;
second_value -= first_value;
second_value *= -1;

Questo ha un comportamento indefinito se una delle operazioni va in overflow o underflow. Può anche perdere precisione se gli oggetti sono in virgola mobile.
Keith Thompson
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.