首页 > 代码库 > Python、C++中编写函数以及不使用临时变量交换两变量值的比较
Python、C++中编写函数以及不使用临时变量交换两变量值的比较
在C++中,交换两变量的值一般第一反应都会是如下的代码:
{ temp=a; a=b; b=temp }
但是题目要求不允许使用临时变量temp呢?可能就需要想一会了。但也有解决办法:
{ b=a+b; a=b-a; b=b-a; }
这种做法在a和b数值较小的情况下是对的,但是a+b如果很大则会溢出,所以也不是最优的解法。最好的方法是使用异或:
{ a ^= b b ^=a a ^=b }
a,b=b,a
直接一行搞定!
如果题目要求编写一个函数来交换两变量的值呢?
在C++中我们都知道需要传递指针或引用作为参数才可以实现交换两变量的值,如下:
void swap(int*a,int* b){ int temp=*a; *a=*b; *b=temp; } int a=3; int b=4; swap(&a,&b);或是更简单的使用引用:
void swap(int &a,int &b){ int t=a; a=b; b=t; }swap(a,b);
但是Python中就不可以了。Python的机制有些难搞(刚接触的时候),它是一种弱类型的语言,所有变量都可以不声明类型直接拿来使用,也可以理解为变量只是内存对象的一种“指向”,变量只是个符号而已,没有任何实际意义,真正具有类型概念的是内存对象。
Python众多类型对象中,又可以分为可变对象(如list、dict)和不可变对象(strings、numbers、tuples)。不可变对象理解起来可以参考C++中的string,就像有一个string池,你不能改变某一个string的内容,但赋值的时候只不过是从string池中挑选不同的string赋给变量。可变对象,顾名思义是可以改变值的对象,举例来说:
a=2
b=[2]
这两句话的效果是,首先在内存中创建了一个整数型对象,值为2,然后令变量a指向该对象。第二句话是创建了一个列表list,然后列表的第一个元素指向刚才内存中的对象“2”,变量b指向创建的列表。我们可以使用id()来查看对象在内存中存储的位置。
可以看到a和b[0]其实指向的是同一块内存区域。这就是在内存中其实只有一个值为2的对象,不管有多少个变量赋值为2,其实都只是指向了这一个对象,那些变量只是起到一个指向的作用,而且这个2是不可以改变的,也就是在这一次的运行过程中,这个内存区域存放的值不变。list则不一样,list的内容是可以变化的。
a=5 b[0]=5
执行这两句过后,id(a)和id(b[0])还和原来一样么?答案是不会啦!看结果:
a=5只是又创建了一个值为5的整数型对象,并且将变量a指向了它,对象2还在原来的位置,不会改变。仔细观察会发现,b的位置一直没有变,变得只是其中的内容,所以说list是可变对象。
弄清了这些,在函数的参数传递过程中,如果只是将指向整数的变量传递,那么其实只是新建了几个变量而已,函数中对参数进行任何修改都只是改变的新变量的指向,而不会对原有变量会有丝毫影响。
为了更清楚地说明,我们在函数中传递的参数名依然是a,不过这个a和外部的可是半毛钱关系都没有,它只是一个符号,b,c,d都一样,没有任何实际意义。可以看到,在调用函数前,a已经指向了对象“2”,在调用函数的时候,将对象的指向这个传递给了函数中的参数a,所以a指向的内存为4893164,这正是前文中内存2的地址。后来赋值5并查看地址也都没有什么问题。当这个函数结束时,这个变量a的生命就到此结束了,一旦退出函数,在查看a的值的时候,它仍然是指向的对象2。这恰好说明了函数中的a和外部的a没有任何的关系。
所以在Python中如果想通过函数来交换两个变量的值的话,我还没有什么好办法,可能只有通过传入list这样的可变对象才能实现吧~
Python、C++中编写函数以及不使用临时变量交换两变量值的比较