博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Swap in C C++ C# Java
阅读量:6590 次
发布时间:2019-06-24

本文共 3471 字,大约阅读时间需要 11 分钟。

写一个函数交换两个变量的值。

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 = 23, b = 47;    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 0;}

预处理之后的代码就是:

int main() {    int a = 23, b = 47;    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 0;}

所以可以正确的交换两个变量的值。

C++:

方式一:如同C语言使用指针。

方式二:使用“引用”(&)

void swap(int& i, int& j) {    int t = i;    i = j;    j = t;}

C++的函数参数使用引用(&),值通过引用传递(pass by reference),函数中的参数不被 copy(如果传的是类就不会调用拷贝构造函数),所以在函数中能正确交换两个变量的值。

C#:

static void Swap
(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 valueclass 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

 

作者:
出处:
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
http://www.cnblogs.com/luxiaoxun/p/3999583.html
你可能感兴趣的文章
Linux文件操作
查看>>
ylbtech-Recode(记录)-数据库设计
查看>>
运动目标跟踪与检测的源代码(CAMSHIFT 算法)
查看>>
PHP工厂模式的简单实现
查看>>
线程同步中异常情况的处理
查看>>
Orchard模块开发全接触3:分类的实现及内容呈现(Display)
查看>>
JQuery 自动触发事件
查看>>
ylbtech-LanguageSamples-CommandLine(命令行参数)
查看>>
Uptime And Monitoring Strategies For Cloud-Based E-Commerce Applications/Websites
查看>>
FPGA未来几年的发展趋势及发展机遇
查看>>
【spring bean】 spring中bean之间的引用以及内部bean
查看>>
MVVM架构~knockoutjs系列之验证信息自定义输出~续
查看>>
-webkit-line-clamp下多行文字溢出点点点...显示实例页面
查看>>
FTP中各文件目录的说明
查看>>
JScript内置对象Array中元素的删除问题
查看>>
Service 广播 到Fragment
查看>>
Eclipse中建立自己的类库,给不同的工程使用
查看>>
记 dotamax 面试第一题
查看>>
ubuntu 64位android项目报错的解决方案,打开64位 Ubuntu 的32位支持功能
查看>>
KBMMW 4.92.00 发布
查看>>