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 = 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<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
作者:阿凡卢
出处:https://www.cnblogs.com/luxiaoxun/p/3999583.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App