Existe uma função de troca incorporada em C?

Existe alguma função de swap incorporada em C que funcione sem usar uma terceira variável?

 28
Author: Mat, 2012-01-14

11 answers

Não.
C++ tem mas funciona como c = a;a = b; b = c;
Função de swap de compilação em C++ : swap(first,second);
Verifique isto: http://www.cplusplus.com/reference/algorithm/swap/

Pode usar isto para trocar dois valores variáveis sem usar a terceira variável:

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

Também pode verificar isto:

Https://stackoverflow.com/questions/756750/swap-the-values-of-two-variables-without-using-third-variable

Como trocar sem uma terceira variável?

 21
Author: Saif, 2017-05-23 12:26:09

Porque não queres usar uma terceira variável? É o caminho mais rápido na grande maioria das arquiteturas.

O algoritmo XOR swap funciona sem uma terceira variável, mas é problemático de duas maneiras:

  1. as variáveis devem ser distintas, ou seja swap(&a, &a) não funcionarão.
  2. É mais lento em geral.

Às vezes pode ser preferível usar a troca de XOR se usar uma terceira variável causaria o derramamento da pilha, mas geralmente você não está em tal uma posição para fazer essa chamada.

Para responder directamente à sua pergunta, não existe nenhuma função de swap na norma C, embora fosse trivial escrever.

 22
Author: Peter Alexander, 2012-01-14 12:18:50

Assumindo que quer umC solotion, não um C++, pode torná-lo uma macro, pelo menos usando a extensão GCC para a ter suficientemente genérica, algo como

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

Cuidado com truques como invocações {[[1]}; para evitá-los, use o operador de endereço &. E você melhor usar um temporário (para inteiros, há um famoso e inútil truque com exclusivo-or).

PS: estou usando duas variáveis locais _x e _y (mas eu poderia ter usado uma variável local somente) para melhor legibilidade, e talvez também para permitir mais otimizações do compilador.

 8
Author: Basile Starynkevitch, 2013-07-28 08:30:41

Não existe tal função na norma C.

(Em C++ tem std::swap().)


Talvez uma macro de esta pergunta possa ser útil para você.

 7
Author: Igor Oks, 2017-05-23 12:18:01

Não existe uma função-padrão em C para trocar duas variáveis.

Uma macro pode ser escrita desta forma:

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

E a macro pode ser chamada assim:

int a = 42;
int b = 2718;

SWAP(int, a, b);
Algumas soluções para uma gravação de uma macro de SWAP devem ser evitadas:
#define SWAP(a, b) do { a = b + a; b = a - b; a = a - b; } while (0)

Quando os operandos são de tipos assinados pode ocorrer um overflow e o overflow assinado é um comportamento indefinido.

Também uma solução que tenta optimizar a solução XOR desta forma deve ser evitada:

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

a é modificado duas vezes entre o ponto de sequência anterior e o próximo, por isso viola as regras de pontos de sequência e é um comportamento indefinido.

 5
Author: ouah, 2012-01-14 13:02:31

Dado que poderá copiar qualquer representação de objectos para uma matriz de caracteres sem sinal em C, a seguinte macro permite-lhe trocar quaisquer dois objectos:

#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)

O GCC irá mesmo gerar o código ideal para isto em alguns casos. Mas podes não manter o teu emprego...

 2
Author: u0b34a0f6ae, 2013-01-13 03:50:51

Existe uma função de biblioteca C++. Ele troca os valores de duas variáveis inteiras. Por exemplo, swap(x, y); troca os valores das variáveis x e y. Da mesma forma, trocar(mat[i][j], mat[j][i]); troca de dois valores na matriz mat, nomeadamente o valor na linha i, coluna j e o valor na linha e j a coluna.

 1
Author: Prinavin Govender, 2014-09-18 18:32:39

Não existe nenhuma função de troca incorporada, mas pode tentar isto

a = a ^ b;

b = a ^ b;

a = b ^ a;

 1
Author: Saif, 2017-12-15 01:13:01

Existe std::swap uma vez que, em geral, depende do teu processador, se suporta o swaping. há uma instrução chamada "comparar e trocar", mas ela só funciona em tipos que se encaixam em um registro e é garantido ser atômico. Existe uma implementação incorporada de comparar e trocar (CAS) de gcc é usado para a sincronização de implementações de thread e mutex e provavelmente está fora de alcance para o seu propósito, por isso é melhor ficar apenas usando uma variável temporária ou se você está realmente preso A C você pode sempre usar uma macro como esta:

#define swap(a,b) a=a^b; \
                  b=a^b; \
                  a=b^a;
 0
Author: Alex, 2012-01-14 12:35:49
Acho que descobri uma função agnóstica tipo para trocar dois valores na norma C, mas como sou novo na linguagem, posso ter esquecido alguma coisa. Ele usa o algoritmo XOR swap, e eu tenho certeza que ele poderia ser otimizado mais, mas ele funciona desde que os dois valores apontam para o mesmo número de bytes, especificado pelo terceiro argumento:
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++;
    }
}

Uso de exemplo:

// 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);

A saída é:

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
Author: Patrick Roberts, 2015-03-06 23:05:47
#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
Author: Li Kui, 2018-07-16 11:52:03