C中是否有内置交换功能,不使用第三个变量?
答案 0 :(得分:27)
没有。
C ++有,但它的工作方式与c = a;a = b; b = c;
一样
C ++内置交换函数:swap(first,second);
检查一下:http://www.cplusplus.com/reference/algorithm/swap/
您可以使用它来交换两个变量值而不使用第三个变量:
a=a^b;
b=a^b;
a=b^a;
您也可以查看:
答案 1 :(得分:24)
为什么你不想使用第三个变量?这是绝大多数架构上最快的方式。
XOR swap algorithm没有第三个变量,但在两个方面存在问题:
swap(&a, &a)
不起作用。有时最好使用XOR交换,如果使用第三个变量会导致堆栈溢出,但通常你不能进行该调用。
直接回答你的问题,标准C中没有交换功能,尽管写起来很简单。
答案 2 :(得分:8)
答案 3 :(得分:8)
假设你想要 C solotion,而不是 C ++ ,你可以把它变成一个宏,至少使用GCC扩展来使它足够通用,比如< / p>
#define SWAP(x,y) do { \
typeof(x) _x = x; \
typeof(y) _y = y; \
x = _y; \
y = _x; \
} while(0)
谨防调用swap(t[i++],i)
之类的技巧;要避免它们,请使用地址运算符&
。而且你最好使用一个临时的(对于整数,有一个着名的,无用的技巧与独占或者)。
PS:我正在使用两个局部变量_x
和_y
(但我本来只能使用一个局部变量)以获得更好的可读性,也许还可以实现更多优化编译器。
答案 4 :(得分:6)
C中没有标准函数来交换两个变量。
宏可以这样写:
#define SWAP(T, a, b) do { T tmp = a; a = b; b = tmp; } while (0)
可以这样调用宏:
int a = 42;
int b = 2718;
SWAP(int, a, b);
应该避免编写SWAP宏的一些解决方案:
#define SWAP(a, b) do { a = b + a; b = a - b; a = a - b; } while (0)
当操作数是有符号类型时,可能发生溢出,有符号溢出是未定义的行为。
同样应该避免尝试优化此类XOR解决方案的解决方案:
#define SWAP(a, b) (a ^= b ^= a ^=b)
a
在前一个和下一个序列点之间被修改两次,因此它违反了序列点规则并且是未定义的行为。
答案 5 :(得分:2)
由于您可以将任何对象表示复制到C中的unsigned char数组中,因此以下宏允许您交换任意两个对象:
#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甚至会在某些情况下为此生成最佳代码。你可能不会继续工作......
答案 6 :(得分:1)
没有内置交换功能,但你可以试试这个
a = a ^ b;
b = a ^ b;
a = b ^ a;
答案 7 :(得分:1)
有一个C ++库函数。它交换两个整数变量的值。例如,swap(x,y);将交换变量x和y的值。同样,交换(mat [i] [j],mat [j] [i]);将在矩阵mat中交换两个值,即第i行第j列中的值和第j行第i列中的值。
答案 8 :(得分:0)
有std::swap
因为一般来说它取决于您的处理器,是否支持交换。有一个称为“比较和交换”的指令,但它只适用于适合寄存器并保证是原子的类型。有一个来自gcc的比较和交换(CAS)的内置实现,它用于线程和互斥实现的同步,可能超出了你的目的范围,所以最好坚持使用临时变量或如果你真的坚持C,你总是可以使用这样的宏:
#define swap(a,b) a=a^b; \
b=a^b; \
a=b^a;
答案 9 :(得分:0)
我相信我已经想出了一个类型无关的函数来交换标准C中的任何两个值,但是因为我对这种语言很新,我可能忽略了一些东西。它使用XOR交换算法,我确信它可以进行更多优化,但只要两个值指向由第三个参数指定的相同字节数,它就可以工作:
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++;
}
}
使用示例:
// 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);
输出结果为:
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
答案 10 :(得分:0)
#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;
}