在C中有内置的交换函数吗?

时间:2022-09-06 12:35:32

Is there any built in swap function in C which works without using a third variable?

C中的swap函数中是否存在不使用第三个变量的情况?

10 个解决方案

#1


21  

No.
C++ has but it works like c = a;a = b; b = c;
C++ builtin swap function: swap(first,second);
Check this: http://www.cplusplus.com/reference/algorithm/swap/

不。C++有C = a;a = b;b = c;c++内建交换函数:swap(first,second);检查:http://www.cplusplus.com/reference/algorithm/swap/

You can use this to swap two variable value without using third variable:

你可以用这个来交换两个变量值而不用第三个变量:

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

You can also check this:

你也可以检查一下:

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

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

How to swap without a third variable?

如何在没有第三个变量的情况下进行交换?

#2


22  

Why do you not want to use a third variable? It's the fastest way on the vast majority of architectures.

为什么你不想使用第三个变量?这是大多数体系结构中最快的方法。

The XOR swap algorithm works without a third variable, but it is problematic in two ways:

XOR交换算法在没有第三个变量的情况下是有效的,但是它有两个问题:

  1. The variables must be distinct i.e. swap(&a, &a) will not work.
  2. 变量必须是不同的,即交换(& & & &)将不起作用。
  3. It is slower in general.
  4. 总的来说它比较慢。

It may sometimes be preferable to use the XOR swap if using a third variable would cause the stack to spill, but generally you aren't in such a position to make that call.

如果使用第三个变量会导致堆栈溢出,有时使用XOR交换可能会更好,但通常情况下,您没有这样的位置来调用该调用。

To answer your question directly, no there is no swap function in standard C, although it would be trivial to write.

为了直接回答你的问题,在标准C中没有交换函数,尽管写起来很简单。

#3


8  

Assuming you want a C solotion, not a C++ one, you could make it a macro, at least using GCC extension to have it generic enough, something like

假设您需要一个C solotion,而不是c++,您可以将它设置为一个宏,至少可以使用GCC扩展使它具有足够的通用性,比如

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

beware of tricks like invocations swap(t[i++],i); to avoid them, use the address operator &. And you'll better use a temporary (for integers, there is a famous and useless trick with exclusive-or).

小心调用交换(t[i++ +],i)之类的技巧;要避免它们,请使用地址操作符&。您最好使用一个临时的(对于整数,有一个著名的和无用的技巧与排除-or)。

PS: I'm using two local variables _x and _y (but I could have used one local variable only) for better readability, and perhaps also to enable more optimizations from the compiler.

PS:我使用了两个局部变量_x和_y(但是我可以只使用一个局部变量)来提高可读性,也许还可以让编译器进行更多的优化。

#4


7  

There is no such function in standard C.

在标准C中没有这样的函数。

(In C++ you have std::swap().)

(在c++中有std::swap()。)


Maybe a macro from this question can be useful for you.

也许这个问题中的宏对你有用。

#5


5  

There is no standard function in C to swap two variables.

在C中没有标准函数来交换两个变量。

A macro can be written this way:

一个宏可以这样写:

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

and the macro can be called this way:

宏观可以这样叫:

int a = 42;
int b = 2718;

SWAP(int, a, b);

Some solutions for a writing a SWAP macro should be avoided:

应该避免编写掉期宏的一些解决方案:

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

when operands are of signed types an overflow can occur and signed overflow are undefined behavior.

当操作数为带符号类型时,可能会发生溢出,带符号溢出是未定义的行为。

Also a solution trying to optimize the XOR solution like this should be avoid:

同样,要避免这样的XOR解决方案,应该避免:

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

a is modified twice between the previous and the next sequence point, so it violates the sequence points rules and is undefined behavior.

在前面和下一个序列点之间修改了两次,因此它违反了序列点规则,并且是未定义的行为。

#6


2  

Since you may copy any object representation into an unsigned char array in C, the following macro allows you to swap any two objects:

由于您可以将任何对象表示复制到C中的无符号字符数组中,因此下面的宏允许您交换任意两个对象:

#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 will even generate optimal code for this in some cases. You might not keep your job though...

在某些情况下,GCC甚至会为此生成最优代码。你可能不会保住你的工作……

#7


1  

There is is a C++ library function. It swaps the values of two integer variables. For example, swap(x, y); will swap the values of variables x and y. Similarly, swap(mat[i][j], mat[j][i]); will swap two values in matrix mat, namely the value in row i column j and the value in row j column i.

有一个c++库函数。它交换两个整数变量的值。例如,交换(x,y);将变量x和y的值进行交换,同样的,交换(mat[i][j], mat[j][i]);将交换矩阵mat中的两个值,即第i行第j列中的值和第j行第i列中的值。

#8


1  

There is no built-in swap function but you can try this

没有内置的交换函数,但是您可以尝试一下

a = a ^ b;

= ^ b;

b = a ^ b;

b = ^ b;

a = b ^ a;

a = b ^;

#9


0  

there is std::swap since in general it depends on your processor, whether it supports swaping. there is an instruction called "compare and swap", but it only works on types that fit into a register and is guaranteed to be atomic. There is a built-in implementation of compare and swap (CAS) from gcc it's used for synchronization of thread and mutex implementations and probably way out of scope for your purpose so it's best to stick with just using a temporary variable or if you are really stuck to C you can always use a macro like this:

这里有std::swap因为通常它取决于你的处理器,它是否支持swacking。有一条指令叫做“比较和交换”,但是它只适用于适合寄存器的类型,并且保证是原子的。有一个内置的实现比较和交换从gcc(CAS)是用于线程的同步和互斥对象实现和可能的范围为目的所以最好坚持只使用一个临时变量或如果你真的坚持C你总是可以使用这样的一个宏:

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

#10


0  

I believe I've come up with a type-agnostic function for swapping any two values in standard C, though since I'm fairly new to the language I may have overlooked something. It uses the XOR swap algorithm, and I'm sure it could be optimized more, but it works as long as the two values point to the same number of bytes, specified by the 3rd argument:

我相信我已经提出了一个与类型无关的函数来交换标准C中的任意两个值,但是由于我对语言相当陌生,我可能忽略了一些东西。它使用了XOR交换算法,我相信它可以优化得更多,但是只要两个值指向相同的字节数,由第3个参数指定:

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++;
    }
}

Example usage:

使用示例:

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

The output is:

的输出是:

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

#1


21  

No.
C++ has but it works like c = a;a = b; b = c;
C++ builtin swap function: swap(first,second);
Check this: http://www.cplusplus.com/reference/algorithm/swap/

不。C++有C = a;a = b;b = c;c++内建交换函数:swap(first,second);检查:http://www.cplusplus.com/reference/algorithm/swap/

You can use this to swap two variable value without using third variable:

你可以用这个来交换两个变量值而不用第三个变量:

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

You can also check this:

你也可以检查一下:

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

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

How to swap without a third variable?

如何在没有第三个变量的情况下进行交换?

#2


22  

Why do you not want to use a third variable? It's the fastest way on the vast majority of architectures.

为什么你不想使用第三个变量?这是大多数体系结构中最快的方法。

The XOR swap algorithm works without a third variable, but it is problematic in two ways:

XOR交换算法在没有第三个变量的情况下是有效的,但是它有两个问题:

  1. The variables must be distinct i.e. swap(&a, &a) will not work.
  2. 变量必须是不同的,即交换(& & & &)将不起作用。
  3. It is slower in general.
  4. 总的来说它比较慢。

It may sometimes be preferable to use the XOR swap if using a third variable would cause the stack to spill, but generally you aren't in such a position to make that call.

如果使用第三个变量会导致堆栈溢出,有时使用XOR交换可能会更好,但通常情况下,您没有这样的位置来调用该调用。

To answer your question directly, no there is no swap function in standard C, although it would be trivial to write.

为了直接回答你的问题,在标准C中没有交换函数,尽管写起来很简单。

#3


8  

Assuming you want a C solotion, not a C++ one, you could make it a macro, at least using GCC extension to have it generic enough, something like

假设您需要一个C solotion,而不是c++,您可以将它设置为一个宏,至少可以使用GCC扩展使它具有足够的通用性,比如

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

beware of tricks like invocations swap(t[i++],i); to avoid them, use the address operator &. And you'll better use a temporary (for integers, there is a famous and useless trick with exclusive-or).

小心调用交换(t[i++ +],i)之类的技巧;要避免它们,请使用地址操作符&。您最好使用一个临时的(对于整数,有一个著名的和无用的技巧与排除-or)。

PS: I'm using two local variables _x and _y (but I could have used one local variable only) for better readability, and perhaps also to enable more optimizations from the compiler.

PS:我使用了两个局部变量_x和_y(但是我可以只使用一个局部变量)来提高可读性,也许还可以让编译器进行更多的优化。

#4


7  

There is no such function in standard C.

在标准C中没有这样的函数。

(In C++ you have std::swap().)

(在c++中有std::swap()。)


Maybe a macro from this question can be useful for you.

也许这个问题中的宏对你有用。

#5


5  

There is no standard function in C to swap two variables.

在C中没有标准函数来交换两个变量。

A macro can be written this way:

一个宏可以这样写:

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

and the macro can be called this way:

宏观可以这样叫:

int a = 42;
int b = 2718;

SWAP(int, a, b);

Some solutions for a writing a SWAP macro should be avoided:

应该避免编写掉期宏的一些解决方案:

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

when operands are of signed types an overflow can occur and signed overflow are undefined behavior.

当操作数为带符号类型时,可能会发生溢出,带符号溢出是未定义的行为。

Also a solution trying to optimize the XOR solution like this should be avoid:

同样,要避免这样的XOR解决方案,应该避免:

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

a is modified twice between the previous and the next sequence point, so it violates the sequence points rules and is undefined behavior.

在前面和下一个序列点之间修改了两次,因此它违反了序列点规则,并且是未定义的行为。

#6


2  

Since you may copy any object representation into an unsigned char array in C, the following macro allows you to swap any two objects:

由于您可以将任何对象表示复制到C中的无符号字符数组中,因此下面的宏允许您交换任意两个对象:

#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 will even generate optimal code for this in some cases. You might not keep your job though...

在某些情况下,GCC甚至会为此生成最优代码。你可能不会保住你的工作……

#7


1  

There is is a C++ library function. It swaps the values of two integer variables. For example, swap(x, y); will swap the values of variables x and y. Similarly, swap(mat[i][j], mat[j][i]); will swap two values in matrix mat, namely the value in row i column j and the value in row j column i.

有一个c++库函数。它交换两个整数变量的值。例如,交换(x,y);将变量x和y的值进行交换,同样的,交换(mat[i][j], mat[j][i]);将交换矩阵mat中的两个值,即第i行第j列中的值和第j行第i列中的值。

#8


1  

There is no built-in swap function but you can try this

没有内置的交换函数,但是您可以尝试一下

a = a ^ b;

= ^ b;

b = a ^ b;

b = ^ b;

a = b ^ a;

a = b ^;

#9


0  

there is std::swap since in general it depends on your processor, whether it supports swaping. there is an instruction called "compare and swap", but it only works on types that fit into a register and is guaranteed to be atomic. There is a built-in implementation of compare and swap (CAS) from gcc it's used for synchronization of thread and mutex implementations and probably way out of scope for your purpose so it's best to stick with just using a temporary variable or if you are really stuck to C you can always use a macro like this:

这里有std::swap因为通常它取决于你的处理器,它是否支持swacking。有一条指令叫做“比较和交换”,但是它只适用于适合寄存器的类型,并且保证是原子的。有一个内置的实现比较和交换从gcc(CAS)是用于线程的同步和互斥对象实现和可能的范围为目的所以最好坚持只使用一个临时变量或如果你真的坚持C你总是可以使用这样的一个宏:

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

#10


0  

I believe I've come up with a type-agnostic function for swapping any two values in standard C, though since I'm fairly new to the language I may have overlooked something. It uses the XOR swap algorithm, and I'm sure it could be optimized more, but it works as long as the two values point to the same number of bytes, specified by the 3rd argument:

我相信我已经提出了一个与类型无关的函数来交换标准C中的任意两个值,但是由于我对语言相当陌生,我可能忽略了一些东西。它使用了XOR交换算法,我相信它可以优化得更多,但是只要两个值指向相同的字节数,由第3个参数指定:

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++;
    }
}

Example usage:

使用示例:

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

The output is:

的输出是:

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