两个变量交换问题:
一:使用中间变量:
方法一:直接变量交换(不推荐)
void swap(int a, int b){
int temp;
if(a!=b)
// 若a==b,则不用交换,交换反而浪费时间。
{
temp=a;
a=b;
b=temp;
}
}
//调用时注意是按值传递。
方法二:一级指针变量交换:(不推荐)
void swap(int * pt1,int * pt2){
int * temp;
if(pt1!=pt2){
temp=pt1;
pt1=pt2;
pt2=temp;
}
}
int main(){
int a=2;
int b=3;
int * p1=&a;
int * p2=&b;
swap(p1,p2);
printf("%d,%d",*p1,*p2);
}
输出的 仍然是2,3;因为指针是按值传递。
方法三:一级指针取内容交换(推荐)
int temp;
// 此种temp ,不要设置为int *,否则需要开辟内存才可以取内容。
if(pt1!=pt2){
temp=*pt1;
*pt1=*pt2;
*pt2=temp;
}
// 此方法为引用传递。
适用: 指针所指向的变量的内存较小。
方法四:二级指针取内容交换(推荐)
void swap(int ** pt1,int ** pt2){
int * temp;
if(pt1!=pt2){
temp=*pt1;
*pt1=*pt2;
*pt2=temp;
}
}
// 此方法为引用传递,调用者的两个一级指针会发生交换。
优点:如果pt1,pt2指向的是一个大内存的数据(如结构体);
则通过交换指针,可以减少大数据内存的读写。
二:不使用中间变量:
(1)算术方法:
1.方法一
void swap(int* a ,int* b){
if(*a!=*b){
*a=*a+*b;// *a+*b可能发生溢出。
*b=*a-*b;// *b=(*a+*b)-*b=*a;
*a=*a-*b;
}
}
使用逗号表达式则只有一个语句:(不推荐)
if(*a!=*b){
*a=(*a = *a+*b, *b = *a-*b, *a-*b);
}
2.方法二:(较好)
void swap(int *a ,int *b){
if(*a!=*b){
*a=*b-*a;
*b=*b-*a;
*a=*a+*b;
}
}
缺点:是只能用于数字类型,字符串之类的就不可以了。
a+b有可能溢出(超出int的范围),溢出是相对的,
+了溢出了,-回来不就好了,
所以溢出不溢出没关系,就是不安全。
(2)异或方法:
void swap(int *a ,int *b){
if(*a!=*b){
*a=*a^*b;
*b=*a^*b;
*a=*a^*b;
}
}
注意:
1). 如果a==b;则出错。
2). 异或运算符总结:
1.异或运算符的3特点:
(1) 0^0=0,0^1=1 0异或任何数=任何数
(2) 1^0=1,1^1=0 1异或任何数=任何数取反
(3) 任何数异或自己=把自己置0
2.异或运算法则:
1. a ^ b = b ^ a
交换律
2. a ^ b ^ c = a ^ (b ^ c) = (a ^ b) ^ c
结合律
3. d = a ^ b ^ c 可以推出 a = d ^ b ^ c
两边同时^ b ^ c
4. a ^ b ^ a = b
3.交换两个变量的 值:
4.加密解密:
如下:
classE
{ public static void main(String args[ ])
{
char a1='十' , a2='点' , a3='进' , a4='攻' ;
char secret='8' ;
a1=(char) (a1^secret);
a2=(char) (a2^secret);
a3=(char) (a3^secret);
a4=(char) (a4^secret);
System.out.println("密文:"+a1+a2+a3+a4);
a1=(char) (a1^secret);
a2=(char) (a2^secret);
a3=(char) (a3^secret);
a4=(char) (a4^secret);
System.out.println("原文:"+a1+a2+a3+a4);
}
}
(3)栈方法:
int exchange(int* x,int* y)
{
stack S;
push(S,*x);
push(S,*y);
*x=pop(S);
*y=pop(S);
}