两个数字交换不用第三个变量

交换函数

注意:虽然不用第三方变量的写法感觉很牛,但是在复杂的程序环境中容易出现bug(下面会举例bug)并且技巧性越强的代码bug越不好找;因此只需掌握不用第三个变量的思路,平时最好用第三个变量来交换两个数字

1.常用,最好理解:用第三方变量协助交换(相当于一瓶可乐,一瓶雪碧交换,用一个空瓶子实现)

void Swap(int *p1 , int *p2)
{
int tmp = *p1;
*p1 = *p2;
*p2 = tmp;
return 0;
}
int main()
{
int a=10;
int b=20;
Swap(&a,&b);
return 0;
}

2.不用第三方变量(重在思路)
2.1 加减交换
a =10 ; b=20
b=a+b 10 30
a=b-a 20 30
b=b-a 20 10

void Swap(int *p1 , int *p2)
{
*p2+=*p1;
*p1=*p2-*p1;
*p2=*p1-*p2;
return 0;
}

同理: b = b - a;
a = a + b;
b = a - b;
也可以

2.2 异或交换
int a =10 ; b=20 (int4个字节中前三个全为0,省略)
0000 1010 (10) 0001 0100(20)
a=a^b 0001 1110 (30) 0001 0100(20)
b=b^a 0001 1110 (30) 0000 1010(10)
a+a^b 0001 0100(20) 0000 1010(10)

     void  Swap(int *p1 , int *p2)
     {
   *p2  ^= *p1;
    *p1 ^= *p2;
    *p2 ^=  *p1;
    return  0;

}

可能存在bug举例:

#include
void  Swap(int *p1 , int *p2)
{
       *p2+=*p1;
        *p1=*p2-*p1;
       *p2=*p2-*p1;
 } 

 void  Reverse(int *arr,int len)//数组逆置
 {
       for(int i=0,j=len-1 ;i<=j; i++,j--)
      {
        Swap(&arr[i],&arr[j]) ;
      }
  }

void Show(int *arr,int len)//打印
{
   for(int i=0;i<len;i++)
   {
     printf("%d ",arr[i]);
    }
    printf("\n");
}


  int main()\
  {
   //int arr[]={1,2,3,4}; 偶数没问题
   int  arr[]={1,2,3};// 奇数,结果出错
   Reverse(arr,sizeof(arr)/sizeof(arr[0]));
   Show(arr,sizeof(arr)/sizeof(arr[0]));
    return 0;
  }
 

两个数字交换不用第三个变量_第1张图片
发现结果出错位子在 数组中间,即 i 和 j 相等时
调试:
两个数字交换不用第三个变量_第2张图片
当 i 和 j 相等,执行Swap第一个语句时,本应 * p2变为 * p2+ * p1;* p1 不变,但调试发现 * p1也变为了 * p2+ * p1;再执行swap剩余语句后,arr[1]=0;

将代码中 i<=j 改为 i

你可能感兴趣的:(c语言)