编写让人抓狂的代码

原帖地址: http://blog.csdn.net/memoleak/article/details/6578606

写程序难,看程序更难,看欠抽的程序那是难上加难。。。

怎么样写一段程序,只有自己能懂?

怎么样写一段程序,让别人看了抓狂?

看看这个程序:

void popo(int *array, int num)
{
    int i,j,temp;
    for(i=0;i<num-1;i++) {
        for(j=i+1;j<num;j++) {
            if(array[i]>array[j]) {
                temp = array[i];
                array[i] = array[j];
                array[j] = temp;
            }
        }
    }
}

这段代码不用解释,大家都能明白是什么意思:泡泡排序。

现在看看怎么样让这段代码变得晦涩难懂。

第一步:消除循环

消除循环的最好方法是使用递归,递归可以让一个复杂的问题简单化,也能让一个简单的问题复杂化。

void popo(int *array, int num)
{
    int i;
    for(i=0;i<num-1;i++) {
        if(array[0]>array[i+1]) {
            array[0] = array[i+1] + array[0];
            array[i+1] = array[0] - array[i+1];
            array[0] = array[0] - array[i+1];
        }
    }
    if(i != 0)
    popo(array+1, num-1);
}
上面的代码中还存在不容易变成递归的循环,没问题,我们将这个循环单独写成函数,这样就可以使用递归了。

void func(int *array, int index)
{
    if(index > 0) {
        if(array[0]>array[index]) {
            array[0] = array[index] + array[0];
            array[index] = array[0] - array[index];
            array[0] = array[0] - array[index];
        }
        func(array, index-1);

    }
}

void popo(int *array, int num)
{
    func(array, num-1);
    if(num != 0)

        popo(array+1, num-1);
}

第二步:合并函数

将不含循环的多个函数合并成一个函数,可以通过增大参数的取值范围来实现。

我们知道:上面func函数的参数index和popo函数的参数num都是正数,那么我们可以将func函数的参数index改成负数,这样就可以实现合并了,具体看下面合并好的函数:

void popo(int *array, int num)
{
    if(num > 1) { 
        popo(array, 1-num);
        popo(array+1, num-1);
    }
    else if(num < 0){

        if(*array>array[-num]) {
            array[0] = array[-num] + array[0];
            array[-num] = array[0] - array[-num];
            array[0] = array[0] - array[-num];

        }

        popo(array, num+1);

    }
}

第三步:消除常量和临时变量

临时变量可以通过增加函数参数或者增加函数参数的范围或者使用重复的表达式来实现,常量可以通过移位和加减运算转换成0和1来表示,而0和1又可以通过参数的逻辑运算来获得,这样转换后的结果将不会包含任何常量。代码如下:

void popo(int *a, int n)
{

    if(n > !!a) { 
        popo(a, !!a-n);
        popo(a+!!a, n-!!a);

    }
    else if(n < !a){
        if(*a>a[-n])
            a[-n]=(*a+=a[-n])-a[-n],*a-=a[-n];

        popo(a, n+!!a);
    }
}

第四步:使用?:运算符

对于一个不含循环的函数,很容易将其控制逻辑用if-else来表示,而if-else又可以用?:运算符来实现。为了让代码更难懂,可以用_,__,___作为变量名;将数组a[3]写成3[a]等等方法来混淆视听。看看最终完成以后的结果吧:

void ___(int *__, int _)
{
    _>!__?(___(__,!!__-_),___(__+!!__,_-!!__)):_<!__?(*__>__[-_]?__[-_]=(*__+=(!__)[__-_])-(-_)[__],*__-=__[-_]:_,___(__,_+!!__)):___;
}

这样即便是一个有经验的程序员,也很难迅速理解上面的代码了。

最后,来测试一下我们的代码:

#include <stdio.h>
void ___(int *__, int _)
{

    _>!__?(___(__,!!__-_),___(__+!!__,_-!!__)):_<!__?(*__>__[-_]?__[-_]=(*__+=(!__)[__-_])-(-_)[__],*__-=__[-_]:_,___(__,_+!!__)):___;
}
int main()
{
    int test[] = {2,23,3453,1,32,32,563,546,238,345,454,646,5634,24,564,35,4,-3,-45,-5};
    int size = sizeof(test)/sizeof(test[0]);
    int i;
    printf("before: ");
    for(i = 0; i<size; i++)
        printf("%d/t",test[i]);
    ___(test, size);
    printf("/nafter: ");
    for(i = 0; i<size; i++)
        printf("%d/t",test[i]);
    printf("/n");
    return 0;
}

chen@chen-desktop:/opt$ gcc -Wall -Werror sort.c -o sort
chen@chen-desktop:/opt$ ./sort
before: 2       23      3453    1       32      32      563     546     238     345     454     646     5634    24      564     35      4       -3      -45     -5
after: -45      -5      -3      1       2       4       23      24      32      32      35      238     345     454     546     563     564     646     3453    5634

下次面试的时候,谁再让你写排序算法,你可以反问对方:不用循环,你能用一条语句实现排序算法吗?

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值