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

用C或c++怎么做呢?


当前回答

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

#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;
}

其他回答

递归?

#include<stdio.h>
#define MAX 1000

int i = 0;
void foo(void) {
    if(i <= 1000) {
         printf("%d", i);
         i++;
    }
}
int main (void) {
    foo();
}

Manglesky的解决方案很棒,但还不够模糊。: -):

#include <stdio.h>
#define TEN(S) S S S S S S S S S S
int main() { int i = 1; TEN(TEN(TEN(printf("%d\n", i++);))) return 0; }

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

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

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

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

很难看透所有已经提出的解决方案,所以这可能是一个重复。

我想要一些相对简单的东西,只有纯C,而不是c++。它使用递归,但与我看到的其他解相反,它只做对数深度的递归。通过查找表可以避免使用条件。

typedef void (*func)(unsigned, unsigned);
void printLeaf(unsigned, unsigned);
void printRecurse(unsigned, unsigned);


func call[2] = { printRecurse, printLeaf };

/* All array members that are not initialized 
   explicitly are implicitly initialized to 0 
   according to the standard. */
unsigned strat[1000] = { 0, 1 };


void printLeaf(unsigned start, unsigned len) {
  printf("%u\n", start);
}

void printRecurse(unsigned start, unsigned len) {
  unsigned half0 = len / 2;
  unsigned half1 = len - half0;
  call[strat[half0]](start, half0);
  call[strat[half1]](start + half0, half1);
}

int main (int argc, char* argv[]) {
  printRecurse(0, 1000);
}

这甚至可以通过使用一个指针动态地完成。相关的变化:

unsigned* strat = 0;

int main (int argc, char* argv[]) {
  strat = calloc(N, sizeof(*strat));
  strat[1] = 1;
  printRecurse(0, N);
}

未经测试,但应该是香草标准C:

void yesprint(int i);
void noprint(int i);

typedef void(*fnPtr)(int);
fnPtr dispatch[] = { noprint, yesprint };

void yesprint(int i) {
    printf("%d\n", i);
    dispatch[i < 1000](i + 1);
}

void noprint(int i) { /* do nothing. */ }

int main() {
    yesprint(1);
}