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

用C或c++怎么做呢?


当前回答

我不认为这是一个“陷阱问题”……”?:"不是条件句,而是运算符。

所以使用递归和?:操作符来检测何时停止?

int recurse(i)
{
   printf("%d\n", i);
   int unused = i-1000?recurse(i+1):0;

}

recurse(1);

或者沿着类似的变态思路……“&”条件中的第二个子句仅在第一个值为真时执行。像这样递归

i-1000 & recurse(i+1);

也许面试官认为这是一个表达而不是一个条件句。

其他回答

丑陋的C答案(每10的幂只展开一个堆栈帧):

#define f5(i) f(i);f(i+j);f(i+j*2);f(i+j*3);f(i+j*4)
void f10(void(*f)(int), int i, int j){f5(i);f5(i+j*5);}
void p1(int i){printf("%d,",i);}
#define px(x) void p##x##0(int i){f10(p##x, i, x);}
px(1); px(10); px(100);

void main()
{
  p1000(1);
}

你可以使用递归。

是这样的:

void Print(int n)
{
  cout<<n<<" ";   
  if(n>1000)
     return
  else
     return Print(n+1)
}    

int main ()
{
  Print(1);
}

更多的预处理程序滥用:

#include <stdio.h>

#define A1(x,y) #x #y "0\n" #x #y "1\n" #x #y "2\n" #x #y "3\n" #x #y "4\n" #x #y "5\n" #x #y "6\n" #x #y "7\n" #x #y "8\n" #x #y "9\n"
#define A2(x) A1(x,1) A1(x,2) A1(x,3) A1(x,4) A1(x,5) A1(x,6) A1(x,7) A1(x,8) A1(x,9)
#define A3(x) A1(x,0) A2(x)
#define A4 A3(1) A3(2) A3(3) A3(4) A3(5) A3(6) A3(7) A3(8) A3(9)
#define A5 "1\n2\n3\n4\n5\n6\n7\n8\n9\n" A2() A4 "1000\n"

int main(int argc, char *argv[]) {
    printf(A5);
    return 0;
}

我觉得好脏;我想我现在要去洗澡了。

OpenMP版本(当然是非有序的):

#include <iostream>
#include <omp.h>

int main(int argc, char** argv)
{
#pragma omp parallel num_threads(1000)
    {           
#pragma omp critical
        {
            std::cout << omp_get_thread_num() << std::endl;
        }
    }

    return 0;
}

(不工作与VS2010 OpenMP运行时(限制为64线程),但工作在linux上,例如,英特尔编译器)

下面是一个有序的版本:

#include <stdio.h>
#include <omp.h>

int main(int argc, char *argv[])
{
  int i = 1;
  #pragma omp parallel num_threads(1000)
  #pragma omp critical
    printf("%d ", i++);
  return 0;
}

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

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

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

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