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?
11 answers
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:
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:
- as variáveis devem ser distintas, ou seja
swap(&a, &a)
não funcionarão.
É 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.
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.
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ê.
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.
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...
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.
Não existe nenhuma função de troca incorporada, mas pode tentar isto
a = a ^ b;
b = a ^ b;
a = b ^ a;
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;
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
#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;
}