有任何不懂的问题可以评论区留言,能力范围内都会一一回答
我们学c语言学完了,那么现在大家想想如何交换两个变量的值呢?
首先第一种方式也就是我们最常用的方式是创建一个中间变量
比如
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main(void) {
int a = 11;
int b = 12;
int c = 0;
printf("a的值是%d,b的值是%d\n",a, b);
c = a;//将a的值暂时存放到c里面,------>a=11,b=12,c=11
a = b;//把b的值给a ------> a=12 ,b=12, c=11
b = c;//把c的值给b ------> a=12,b=11,c=11
printf("a的值是%d,b的值是%d\n", a, b);
return 0;
}
用指针也是同理
#include <stdio.h>
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
int main() {
int x = 10, y = 20;
printf("Before swap: x = %d, y = %d", x, y);
swap(&x, &y);
printf("After swap: x = %d, y = %d", x, y);
return 0;
}
但是思考,如果不允许创建中间变量呢?
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main(void) {
int a = 11;
int b = 12;
printf("a的值是%d,b的值是%d\n",a, b);
a = a + b;//--->a=23,b=12
b = a - b;//---->a=23,b=11
a = a - b;//---->a=12,b=11
printf("a的值是%d,b的值是%d\n", a, b);
return 0;
}
这样似乎可行啊?但是有一个严重的风险就是,我们知道每个数据类型的大小是有范围的,比如int能表示的值是-2147483648到2147483647但是可能a+b或者a-b的值不在范围内,从而导致交换失败。
那么再想想有没有更好的办法,比如最近学的移位操作符和位操作符呢?
接下来我将像大家讲一个新的方法
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main(void) {
int a = 11;
int b = 12;
printf("a的值是%d,b的值是%d\n",a, b);
a = a ^ b;
b = a ^ b;/*(把第一个式子代入得,b = a ^ b ^ b = a)*/
a = a ^ b;/*(把第二个式子带入得,a = a ^ b = a ^ b ^ a = b)*/
printf("a的值是%d,b的值是%d\n", a, b);
return 0;
}
引理
3^3=0
-3^-3
-3原码 1000 0000 0000 0000 0000 0000 0000 0011
-3补码 1111 1111 1111 1111 1111 1111 1111 1101
-3补码 1111 1111 1111 1111 1111 1111 1111 1101
-3^-3=0 0000 0000 0000 0000 0000 0000 0000 0000
0^-3
-3补码 1111 1111 1111 1111 1111 1111 1111 1101
0的补码 0000 0000 0000 0000 0000 0000 0000 0000
0^3=-3 1111 1111 1111 1111 1111 1111 1111 1101
n^n=0 ,0^n=n
同样0^3^3和3^3^0值相同,满足交换律
故可以这样交换a,b的值
a=a^b;
b=a^b;(把第一个式子代入得,b=a^b^b=b^b^a=0^a=a)
a=a^b;(把第二个式子带入得,a=a^b=a^b^a=a^a^b=b)
从而实现了交换
缺点可读性差,难理解
上面三种方式各有各的优势,最后用思维导图做一个总结