小朋友学C语言(25):两数交换
来源:互联网 发布:九仙图仙羽进阶数据 编辑:程序博客网 时间:2024/05/07 02:08
(一)
#include <stdio.h>int main(){ int a = 10; int b = 5; printf("Before swap: a = %d, b = %d\n", a, b); int temp = a; a = b; b = temp; printf("After swap: a = %d, b = %d\n", a, b); return 0;}
运行结果:
Before swap: a = 10, b = 5After swap: a = 5, b = 10
分析:temp = a,这里等号表示赋值。左边的temp表示变量,右边的a表示a的值。
只能把一个常量(a的值)赋值给变量(temp)。
不要理解成是把变量a赋值给变量temp。因为变量不能赋值给变量。
temp = a,得到temp = 10
a = b,得到a = 5
b = temp,得到 b = 10
(二)
#include <stdio.h>int main(){ int a = 10; int b = 5; printf("Before swap: a = %d, b = %d\n", a, b); a ^= b; b ^= a; a ^= b; printf("After swap: a = %d, b = %d\n", a, b); return 0;}
运行结果:
Before swap: a = 10, b = 5After swap: a = 5, b = 10
分析:请用笔和纸计算下面三个式子的值
a ^= b(等价于a = a ^ b。表示先求a和b的异或结果,再把结果赋值给a。)
b ^= a(等价于b = b ^ a)
a ^= b(等价于a = a ^ b)
(三)
#include <stdio.h>int main(){ int a = 10; int b = 5; printf("Before swap: a = %d, b = %d\n", a, b); a = a + b; b = a - b; a = a - b; printf("After swap: a = %d, b = %d\n", a, b); return 0;}
运行结果:
Before swap: a = 10, b = 5After swap: a = 5, b = 10
分析:请口算或用纸笔计算下面三个式子:
a = a + b;
b = a - b;
a = a - b;
(四)注意
如果数很大的话,采用(三)中的方法,a = a + b这一步,有可能发出内存溢出现象
#include <stdio.h>int main(){ int a = 2147483647; int b = 1; printf("Before swap: a = %d, b = %d\n", a, b); a = a + b; printf("After addition: a = %d\n", a); b = a - b; a = a - b; printf("After swap: a = %d, b = %d\n", a, b); return 0;}
运行结果:
Before swap: a = 2147483647, b = 1After addition: a = -2147483648After swap: a = 1, b = 2147483647
这里a + b得到的竟然是一个负数!这是什么回事呢?
这跟整型的取值范围有关。int类型占4个字节,也就是32位。
最左边那位为符号,0代表正号,1代表负号。
这里10000000,00000000,00000000,00000000相当于十进制的多少呢?是-0吗?
如果是-0的话,因为0无所谓正负,-0就是0,这会导致计算机里面有两种方式表示0。这是不允许的。那么这个数到底表示多少呢?
事实上,这个数很特殊。最左边的1不仅表示负号,还参与了运算
10000000,00000000,00000000,00000000
= - 2 ^ 31
= - 2147483648
这样,程序中a = a + b得到了负数就好理解了。
接下来因为减掉之后,数变小了,又变回正常的正数了。
从这里可以看出,int类型的取值范围为[-2147483648, 2147483647], 即[-2^31, 2^31-1]
(五)结论
(1)使用(三)中的方法交换两数后,如果数很大的话 ,中间a = a + b有可能得到错误的值,但最终的结果是正确的。
(2)如果数很大的话,比如a = 2147483647; b = 1;a = a + b的期望结果是214748364,但是因为这个数不在int的取值范围内,所以得到了一个负数。这个叫做内存溢出(可联想为:米缸装满了,再也装不进去,继续装的话,米就会溢出来了)。
内存溢出是一种程序漏洞,有可能被黑客所利用并攻击(可联想为:米被老鼠吃了)。
所以,建议不要使用(三)中的方法来交换两个数。
更多内容请关注微信公众号
- 小朋友学C语言(25):两数交换
- 小朋友学C++(14):两数交换
- 小朋友学C语言(3):整数、浮点数、字符
- 小朋友学C语言(6):加法
- 小朋友学C语言(12):判断
- 小朋友学C语言(18):二进制
- 小朋友学C语言(20):数组
- 小朋友学C语言(21):字符串
- 小朋友学C语言(22):循环
- 小朋友学C语言(28):指针
- 小朋友学C语言(4):单精度浮点数与双精度浮点数
- 小朋友学C语言-汇总
- C语言 最快的两数交换
- C语言实现两数交换函数
- C语言实现两数交换函数
- C语言两数实现交换
- C语言实现两数的交换
- c语言实现两数交换
- 1861: [Zjoi2006]Book 书架
- 小朋友学C语言(24):位运算符
- 我的CSDN博客开通啦
- [队内测试Day10.24Final]逆序对+表达式计算+贪心+图论+数论?
- OKHtt自己封装
- 小朋友学C语言(25):两数交换
- java_se 内部类-成员内部类
- 调用系统相机
- 小朋友学C语言(26):冒泡排序
- 《python核心编程第二版》第六章 习题补充
- 第八周项目实践2 建立连串算法库
- The difference between Go and C-like language
- 小朋友学C语言(27):选择排序
- 什么是法西斯?