Swap in C C++ C# Java
写一个函数交换两个变量的值。
C:
错误的实现:
void swap(int i, int j)
{
int t = i;
i = j;
j = t;
}
因为C语言的函数参数是以值来传递的(pass by value),参数传递时被copy了,所以函数中交换的是复制后的值。
正确的实现:
指针版:
void swap(int *i, int *j)
{
int t = *i;
*i = *j;
*j = t;
}
函数使用时候传递的是变量的地址,如 swap(&a,&b),函数交换的是两个指针指向的值,就是两个变量的值,所以交换成功。
预处理版:
#define swap(type, i, j) {type t = i; i = j; j = t;}
预处理的实质是文本替换(textual substitution)。
如下代码:
#define swap(type, i, j) {type t = i; i = j; j = t;}
int main()
{
int a = , b = ;
printf("Before swap. a: %d, b: %d\n", a, b);
swap(int, a, b)
printf("After swap. a: %d, b: %d\n", a, b);
return ;
}
预处理之后的代码就是:
int main()
{
int a = , b = ;
printf("Before swap. a: %d, b: %d\n", a, b);
{ int t = a ; a = b ; b = t ; }
printf("After swap. a: %d, b: %d\n", a, b);
return ;
}
所以可以正确的交换两个变量的值。
C++:
方式一:如同C语言使用指针。
方式二:使用“引用”(&)
void swap(int& i, int& j)
{
int t = i;
i = j;
j = t;
}
C++的函数参数使用引用(&),值通过引用传递(pass by reference),函数中的参数不被 copy(如果传的是类就不会调用拷贝构造函数),所以在函数中能正确交换两个变量的值。
C#:
static void Swap<T>(ref T lhs, ref T rhs)
{
T temp;
temp = lhs;
lhs = rhs;
rhs = temp;
}
不要忘了ref关键字,如果没有是不能正确交换的!
Java:
java.util.Collections;
public static void swap(List<?> list,int i,int j)
使用集合中的static方法。
如果不使用数组集合,Java中没有一个简单的函数来交换两个变量的值。除非自己封装一下:
// MyInteger: similar to Integer, but can change value
class MyInteger {
private int x; // single data member
public MyInteger(int xIn) { x = xIn; } // constructor
public int getValue() { return x; } // retrieve value
public void insertValue(int xIn) { x = xIn;} // insert
} public class Swapping {
// swap: pass references to objects
static void swap(MyInteger rWrap, MyInteger sWrap) {
// interchange values inside objects
int t = rWrap.getValue();
rWrap.insertValue(sWrap.getValue());
sWrap.insertValue(t);
} public static void main(String[] args) {
int a = 23, b = 47;
System.out.println("Before. a:" + a + ", b: " + b);
MyInteger aWrap = new MyInteger(a);
MyInteger bWrap = new MyInteger(b);
swap(aWrap, bWrap);
a = aWrap.getValue();
b = bWrap.getValue();
System.out.println("After. a:" + a + ", b: " + b);
}
}
C#这点和Java是一样的,C#版的交换如果不使用ref关键字,swap函数也没法正确工作。
虽然C#、java通过函数参数可以修改参数的值,但是这点和C++的引用有很大的区别。
看看如下函数:
public void tricky(Point arg1, Point arg2)
{
arg1.x = 100;
arg1.y = 100;
Point temp = arg1;
arg1 = arg2;
arg2 = temp;
} public static void main(String [] args)
{
Point pnt1 = new Point(0,0);
Point pnt2 = new Point(0,0);
System.out.println("X: " + pnt1.x + " Y: " +pnt1.y);
System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);
System.out.println(" ");
tricky(pnt1,pnt2);
System.out.println("X: " + pnt1.x + " Y:" + pnt1.y);
System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);
}
执行这个函数,将得到以下输出:
———————————————————-
X: 0 Y: 0
X: 0 Y: 0
X: 100 Y: 100
X: 0 Y: 0
———————————————————-
当Java传递对象给函数之后,两个引用指向了同一对象:

当被传递给函数之后,一个对象至少存在两个引用
Java复制并传递了“引用”的值,而不是对象。因此,方法中对对象的计算是会起作用的,因为引用指向了原来的对象。但是因为方法中对象的引用是“副本”,所以对象交换就没起作用。如下图所示,交换动作只对方法中的引用副本起作用了,不影响方法外的引用。所以不好意思,方法被调用后,改变不了方法外的对象的引用。如果要对方法外的对象引用做交换,我们应该交换原始的引用,而不是它的副本。

只有传入函数的引用交换了,原始引用则没有。
参考:
http://www.cs.utsa.edu/~wagner/CS2213/swap/swap.html
http://stackoverflow.com/questions/1363186/is-it-possible-to-write-swap-method-in-java
http://www.importnew.com/3559.html
Swap in C C++ C# Java的更多相关文章
- Swap Nodes in Pairs leetcode java
题目: Given a linked list, swap every two adjacent nodes and return its head. For example, Given 1-> ...
- 故障重现(内存篇2),JAVA内存不足导致频繁回收和swap引起的性能问题
背景起因: 记起以前的另一次也是关于内存的调优分享下 有个系统平时运行非常稳定运行(没经历过大并发考验),然而在一次活动后,人数并发一上来后,系统开始卡. 我按经验开始调优,在每个关键步骤的加入如 ...
- JAVA CAS原理深度分析-转载
参考文档: http://www.blogjava.net/xylz/archive/2010/07/04/325206.html http://blog.hesey.net/2011/09/reso ...
- 【转】JAVA CAS原理深度分析
java.util.concurrent包完全建立在CAS之上的,没有CAS就不会有此包.可见CAS的重要性. CAS CAS:Compare and Swap, 翻译成比较并交换. java.uti ...
- JAVA CAS原理深度分析
参考文档: http://www.blogjava.net/xylz/archive/2010/07/04/325206.html http://blog.hesey.net/2011/09/reso ...
- JAVA CAS原理深度分析(转)
看了一堆文章,终于把JAVA CAS的原理深入分析清楚了. 感谢GOOGLE强大的搜索,借此挖苦下百度,依靠百度什么都学习不到! 参考文档: http://www.blogjava.net/xylz/ ...
- JAVA内存关注总结,作为个程序员需要对自己系统的每块内存做到了如指掌
服务器的JAVA进程使用的内存是否正常 服务器中,JAVA进程的内存占用= JVM内存+ JAVA堆最大内存大小(Xmx)+JAVA堆外内存大小+栈区( 线程数* Xss) 最需要关注: 1., 服务 ...
- 入我新美大的Java后台开发面试题总结
静儿最近在总结一些面试题,那是因为做什么事情都要认真.面试也一样,静儿作为新美大金融部门的面试官,负责任的告诉大家,下面的问题回答不上来,面试是过不了的.不过以下绝不是原题,你会发现自己实力不过硬,最 ...
- 磁盘管理 之 parted命令添加swap,文件系统
第1章 磁盘管理 1.1 必须要了解的. 1.1.1 ps aux 命令中 RSS 与VSZ的含义 rss 进程占用的物理内存的大小 单位:kb : vsz 进程占用的虚拟的内存大小(物理内存+swa ...
随机推荐
- 利用HTML5定位功能,实现在百度地图上定位
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- iOS 图片大小压缩 图片尺寸处理
图片的压缩其实是俩概念,1.是 “压” 文件体积变小,但是像素数不变,长宽尺寸不变,那么质量可能下降,2.是 “缩” 文件的尺寸变小,也就是像素数减少.长宽尺寸变小,文件体积同样会减小. 这个 UII ...
- iOS - 适配器模式场景总结
适配器模式: 1.出现场景 TableViewCell视图层 - 输出 无论NSData怎么变化,数据都可以显示在视图层中. 2.组成结构 输入 - [适配器]- 输出 (数据层) - [适配器]- ...
- 用File判断D盘下面是否还有txt文件
package cn.idcast; import java.io.File; public class File1 { public static void main(String[] args) ...
- VTK初学一,比较常见的错误2
我的开发环境: 系统:win8.1 QT:5.4.2MinGW版 VTK:6.3 按照教程生成一个球体显示在,Qt的QVTKWidget控件中,出现如下ERROR: ERROR: In D:\VTK6 ...
- js创建,获取,检测cookie
- PHP如何判断一个数组是一维数组或者是二维数组?用什么函数?
如题:如何判断一个数组是一维数组或者是二维数组?用什么函数? 判断数量即可 <?php if (count($array) == count($array, 1)) { echo '是一维数组' ...
- 03OC的类的补充
上一章我们介绍了类的定义,以及类的里面如何定义成员变量,如何定义方法等等. 一.self关键字 1.在C#中有关键字this表示当前对象,其实在OC中也有类似的关键字self,只是self关键字不仅表 ...
- C++文件读写详解
http://blog.csdn.net/kingstar158/article/details/6859379/
- 各大浏览器hack
浏览器界的奇葩IE 样式前缀法,在需要制定某些浏览器只识别其中某些属性的时候: chrome/safari 都是webkit内核的浏览器.在属性前加前缀-webkti- firefox 只在火狐浏览器 ...