任务:打印从1到1000的数字,不使用任何循环或条件语句。不要只写printf()或cout语句1000次。

用C或c++怎么做呢?


当前回答

我不想破坏它,但递归和循环在机器级别本质上是相同的事情。

区别在于JMP/JCC与CALL指令的使用。两者都有大致相同的周期时间,并刷新指令管道。

我最喜欢的递归技巧是手工编写返回地址的PUSH,并对函数使用JMP。然后函数正常工作,并在结束时返回,但返回到其他地方。这对于更快地解析非常有用,因为它减少了指令管道刷新。

最初的海报可能是一个完整的展开,这是模板的人想出的;或者将页内存放入终端,如果您确切地知道终端文本存储在哪里。后者需要大量的洞察力和风险,但几乎不需要计算能力,并且代码没有像连续1000个打印文件那样的麻烦。

其他回答

再举一个异常终止的例子。这一次调整堆栈大小以在1000次递归时耗尽。

int main(int c, char **v)
{
    static cnt=0;
    char fill[12524];
    printf("%d\n", cnt++);
    main(c,v);
}

在我的机器上打印1到1000

995
996
997
998
999
1000
Segmentation fault (core dumped)
#include <stdio.h>
void main(int i){printf("%d\n",i)&&i++<1000&&(*((int*)&i-1)-=5);} 

另一个:

#include <stdio.h>
int main(int i){return i<=1000&&printf("%d\n",i)&&main(++i);}

以下是我知道的三个解决方案。不过,第二种说法可能存在争议。

// compile time recursion
template<int N> void f1()
{ 
    f1<N-1>(); 
    cout << N << '\n'; 
}

template<> void f1<1>() 
{ 
    cout << 1 << '\n'; 
}

// short circuiting (not a conditional statement)
void f2(int N)
{ 
    N && (f2(N-1), cout << N << '\n');
}

// constructors!
struct A {
    A() {
        static int N = 1;
        cout << N++ << '\n';
    }
};

int main()
{
    f1<1000>();
    f2(1000);
    delete[] new A[1000]; // (3)
    A data[1000]; // (4) added by Martin York
}

[编辑:(1)和(4)只能用于编译时常数,(2)和(3)也可以用于运行时表达式-结束编辑。]]

如果POSIX解决方案被接受:

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/time.h>
#include <pthread.h>

static void die(int sig) {
    exit(0);
}

static void wakeup(int sig) {
    static int counter = 1;
    struct itimerval timer;
    float i = 1000 / (1000 - counter);

    printf("%d\n", counter++);

    timer.it_interval.tv_sec = 0;
    timer.it_interval.tv_usec = 0;
    timer.it_value.tv_sec = 0;
    timer.it_value.tv_usec = i; /* Avoid code elimination */
    setitimer(ITIMER_REAL, &timer, 0);
}

int main() {
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    signal(SIGFPE, die);
    signal(SIGALRM, wakeup);
    wakeup(0);
    pthread_mutex_lock(&mutex);
    pthread_mutex_lock(&mutex); /* Deadlock, YAY! */
    return 0;
}

既不是循环语句也不是条件语句,至少它不会在我的机器上崩溃:)。使用一些指针魔法我们有。

#include <stdlib.h>
#include <stdio.h>

typedef void (*fp) (void *, int );

void end(fp* v, int i){
    printf("1000\n");
    return;
}

void print(fp *v, int i)
{
    printf("%d\n", 1000-i);
    v[i-1] = (fp)print;
    v[0] = (fp)end;
    (v[i-1])(v, i-1);

}

int main(int argc, char *argv[])
{
    fp v[1000];

    print(v, 1000);

    return 0;
}