任务:打印从1到1000的数字,不使用任何循环或条件语句。不要只写printf()或cout语句1000次。
用C或c++怎么做呢?
任务:打印从1到1000的数字,不使用任何循环或条件语句。不要只写printf()或cout语句1000次。
用C或c++怎么做呢?
当前回答
#include <cstdlib>
#include <iostream>
#include <string>
using namespace std;
class Printer
{
public:
Printer() { cout << ++i_ << "\n"; }
private:
static unsigned i_;
};
unsigned Printer::i_ = 0;
int main()
{
Printer p[1000];
}
其他回答
我不想破坏它,但递归和循环在机器级别本质上是相同的事情。
区别在于JMP/JCC与CALL指令的使用。两者都有大致相同的周期时间,并刷新指令管道。
我最喜欢的递归技巧是手工编写返回地址的PUSH,并对函数使用JMP。然后函数正常工作,并在结束时返回,但返回到其他地方。这对于更快地解析非常有用,因为它减少了指令管道刷新。
最初的海报可能是一个完整的展开,这是模板的人想出的;或者将页内存放入终端,如果您确切地知道终端文本存储在哪里。后者需要大量的洞察力和风险,但几乎不需要计算能力,并且代码没有像连续1000个打印文件那样的麻烦。
经过一些修改,我想出了这个:
template<int n>
class Printer
{
public:
Printer()
{
std::cout << (n + 1) << std::endl;
mNextPrinter.reset(new NextPrinter);
}
private:
typedef Printer<n + 1> NextPrinter;
std::auto_ptr<NextPrinter> mNextPrinter;
};
template<>
class Printer<1000>
{
};
int main()
{
Printer<0> p;
return 0;
}
后来@ybungalobill的作品启发我想出了这个更简单的版本:
struct NumberPrinter
{
NumberPrinter()
{
static int fNumber = 1;
std::cout << fNumber++ << std::endl;
}
};
int main()
{
NumberPrinter n[1000];
return 0;
}
触发致命错误!这是文件,counup .c:
#include <stdio.h>
#define MAX 1000
int boom;
int foo(n) {
boom = 1 / (MAX-n+1);
printf("%d\n", n);
foo(n+1);
}
int main() {
foo(1);
}
编译,然后在shell提示符下执行:
$ ./countup
1
2
3
...
996
997
998
999
1000
Floating point exception
$
这确实打印了从1到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)
以下是我知道的三个解决方案。不过,第二种说法可能存在争议。
// 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)也可以用于运行时表达式-结束编辑。]]