c语言,python实现汉诺塔,关于闭包的思考

最简单的汉诺塔实现就是递归,比如c语言的实现:

void move(char A,int n,char C){
    printf("%d,%c,%c\n",n,A,C);
}

void Hanoi(int n,char A,char B,char C){
    if(n==1) move(A, 1, C,m);
    else{
        Hanoi(n-1,A,C,B);
        move(A, n, C);
        Hanoi(n-1,B,A,C);
    }
}

但是如果想给move函数打印的时候追加序号来显示移动盘子是第几次操作,则需要一个单独的变量用于计数,手头一本教材上非常简单的设置了一个全局变量,并把变量置于move函数中自增长。

所以在单线程程序里面,多次调用Hanoi(int n,char A,char B,char C),就得重置这个全局变量。

相关实现:

int m=0;

void move(char A,int n,char C){
    printf("[%d]%d,%c,%c\n",++m,n,A,C);
}

void Hanoi_(int n,char A,char B,char C){
    if(n==1) move(A, 1, C);
    else{
        Hanoi_(n-1,A,C,B);
        move(A, n, C);
        Hanoi_(n-1,B,A,C);
    }
}
void Hanoi(int n,char A,char B,char C){
    initHanoi();
    Hanoi_(n,A,B,C);
}
void initHanoi(){//这个代码在多线程程序中一定会出问题
    m=0;
}

在多线程程序中这个代码必定会出现问题的,如果给m加锁,它就和单线程没有区别了。这个问题最简单的处理方法就是闭包,让变量m只被Hanoi(int n,char A,char B,char C)访问的到,外部不能访问,并且每次调用它得到的m只是一个副本,它们的数据不会相互影响。

然而谷歌的结果是C语言不能像python那样的方法实现闭包,一定要写也可以,那是苹果公司在clang上面加上的闭包特性,只有clang编译器支持,clang的写法是不通用的。

python的闭包实现:

def Hanoi(n,A,B,C):
    m=0
    def move(A,n,C):
        nonlocal m
        m+=1
        print("[%d]%d,%c,%c" %(m,n,A,C))
    def Hanoi_(n,A,B,C):
        if n==1:
            move(A, 1, C)
        else:
            Hanoi_(n - 1, A, C, B)
            move(A, n, C)
            Hanoi_(n - 1, B, A, C)
    Hanoi_(n,A,B,C)//闭包其实要写成 return Hanoi_,只是这里只需要调用一次

其实想想,C语言也能写出类似闭包的写法,只是要传参数而已:

void move(char A,int n,char C,int &m){
    printf("[%d]%d,%c,%c\n",++m,n,A,C);
}

void Hanoi_(int n,char A,char B,char C,int &m){
    if(n==1) move(A, 1, C,m);
    else{
        Hanoi_(n-1,A,C,B,m);
        move(A, n, C,m);
        Hanoi_(n-1,B,A,C,m);
    }
}
void Hanoi(int n,char A,char B,char C){
    int m=0;
    Hanoi_(n,A,B,C,m);
}
有点闭包的味道了,23333333

----------------------------------------------------------

我这些写法并不是完整严格的闭包概念,不过闭包目前对我而言只是不去给变量加锁的偷懒方法而已,先这样吧。

闭包定义的讨论:https://www.ibm.com/developerworks/cn/linux/l-cn-closure/

根据该文章的说法,闭包和返回函数也没有必然关系,看来也只是一种形式而已,闭包的有一层意义是函数执行完成之后,它的成员变量不会被回收,因为这个变量要给函数返回的函数去执行。而我只是用了它另一个作用,每次调用函数,内部函数相当于使用的是外部变量的副本,这样就能避免数据相互影响,这也是类似一种包啊。

为了写闭包而闭包是没有必要的,要关注的是闭包的实际服务作用,按实际需要而写。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值