高频面试题-如何交换两个变量值?办法没你想得那么多!

​来源:公众号【编程珠玑】

作者:守望先生

ID:shouwangxiansheng

 

C语言交换两个整型变量,你有哪些方法?那么多方法,又有哪几个可行?

不可行的方法

初学者最容易理解错的方法:

//来源:公众号【编程珠玑】
//https://www.yanbinghu.com
#include<stdio.h>
void swap(int a,int b)
{
    int temp = a;
    a = b;
    b = temp;
}
int main(void)
{
    int a = 10;
    int b = 24;
    swap(a,b);
    //输出a = 10,b = 20
    printf("a = %d,b = %d\n",a,b);
    return 0;
}

不理解为何不行的请参考《传值与传指针》。

理解实参只是原数据的一个拷贝,非常关键。

可行方法

这里最容易想到的一种方法:

//来源:公众号【编程珠玑】
//https://www.yanbinghu.com
#include<stdio.h>
void swap(int *a,int *b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
}
int main(void)
{
    int a = 10;
    int b = 24;
    swap(&a,&b);
    //输出a = 24,b = 10 
    printf("a = %d,b = %d\n",a,b);
    return 0;
}

但是有人还试图用类似的方法交换字符串,那就不可取了:

//来源:公众号【编程珠玑】
//https://www.yanbinghu.com
#include<stdio.h>
void swap(char *a,char *b)
{
    char *temp = a;
    a = b;
    b = temp;
}
int main(void)
{
    char a[] = "hello";
    char b[] = "world";
    swap(a,b);
    //输出a = hello,b = world
    printf("a = %s,b = %s\n",a,b);
    return 0;
}

什么?为什么没有像你预期那样交换a和b的内容?还是参考《传值与传指针》。

不借助临时变量一

//来源:公众号【编程珠玑】
//https://www.yanbinghu.com
#include<stdio.h>
void swap(int *a,int *b)
{
    *a = *a + *b; //10 + 24 = 34 ,有溢出的风险
    *b = *a - *b; //34 - 24 = 10
    *a = *a - *b; //34 - 10 = 24
    //变体如下:
    //*a = (*a + *b) - (*b = *a);
}

不过这个方法的缺点非常明显,那就是存在溢出的风险。

还有下面这种类似的方法:

void swap(int *a,int *b)
{
    *a = *a * *b;
    *b = *a / *b;
    *a = *a / *b;
}

这种方法除了有溢出风险外,b还不能为0。

不借助临时变量二

void swap(int *a,int *b)
{
    *a = *a ^ *b;
    *b = *a ^ *b;
    *a = *a ^ *b;
    //变体如下
    //*a = (*a ^ *b) ^ (*b ^ *a);
}

没错,就是采用异或,相同异或(0^0=0;1^1=0)结果为0,不同异或(0^1 = 1)结果为1。

*a = *a ^ *b:

01010a = 10
11000b = 24
10010a = a ^ b = 18

*b = *a ^ *b:

10010a = 18
11000b = 24
01010b = a ^ b = 10

*a = *a ^ *b:

10010a = 18
01010b = 10
11000a = a ^ b = 24

不过这种方法中,如果传入参数指向同一地址,它并不如预期那样工作:

//来源:公众号【编程珠玑】
//https://www.yanbinghu.com
#include<stdio.h>
void swap(int *a,int *b)
{
    *a = *a ^ *b;
    *b = *a ^ *b;
    *a = *a ^ *b;
}
int main(void)
{
    int a = 10;
    swap(&a,&a);//都传入a
    //输出a = 0
    printf("a = %d\n",a);
    return 0;
}

至于前面提到的不借助第三个变量的方法,你都可以尝试一下,它可能不如你预期那样工作奥!

既然如此,可以稍微改进一下:

void swap(int *a,int *b)
{
    if(a != b)
    {
        *a = *a ^ *b;
        *b = *a ^ *b;
        *a = *a ^ *b;
    }
}

总结

那么问题来了,那种方式更快呢?

答案可能让你意外:
在编译器的优化下,使用临时变量的方式可能是最快的。

你还有什么方法交换两个整数的值?欢迎留言。

#include<iostream>
int main()
{
    std::string a = "10";
    std::string b = "24";
    std::swap(a,b);
    std::cout<<"a="<<a<<";b="<<b<<std::endl;
    return 0;
}
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页