有这样一个面试题——请把从1到1000的数打印出来,但你不能使用任何的循环语句或是条件语句。更不能写1000个printf或是cout。用C/C++语言。
我相信,大多数人一开始你可能想到的是递归算法:
- void f(int n){
-
printf("%d\n",n);
-
(1000-n) ? f(n+1) : exit(0) ;
-
}
-
int main(){
-
f(1);
-
}
当然,题目中说了不能使用条件语句,所以,上面那种解法的不符合题意的,因为还是变向地使用了条件表达式。不过,我们可以用别的方法来让这个递归终止,比如:
除以零,当程序crash,呵呵
void f(int n){ printf("%d\n",n); n/(1000-n); f(n+1); } |
还有这样退出递归的:
- void yesprint(int i);
-
void noprint(int i);
-
-
typedef void(*fnPtr)(int);
-
fnPtr dispatch[] = { yesprint, noprint };
-
-
void yesprint(int i) {
-
printf("%d\n", i);
-
dispatch[i / 1000](i + 1);
-
}
-
-
void noprint(int i) { /* do nothing. */ }
-
-
int main() {
-
yesprint(1);
-
}
还有下面这些各种各样的解法:
- #include<stdio.h>
-
-
/* prints number i */
-
void print1(int i) {
-
printf("%d\n",i);
-
}
-
-
/* prints 10 numbers starting from i */
-
void print10(int i) {
-
print1(i);
-
print1(i+1);
-
print1(i+2);
-
print1(i+3);
-
print1(i+4);
-
print1(i+5);
-
print1(i+6);
-
print1(i+7);
-
print1(i+8);
-
print1(i+9);
-
}
-
-
/* prints 100 numbers starting from i */
-
void print100(int i) {
-
print10(i);
-
print10(i+10);
-
print10(i+20);
-
print10(i+30);
-
print10(i+40);
-
print10(i+50);
-
print10(i+60);
-
print10(i+70);
-
print10(i+80);
-
print10(i+90);
-
}
-
-
/* prints 1000 numbers starting from i */
-
void print1000(int i) {
-
print100(i);
-
print100(i+100);
-
print100(i+200);
-
print100(i+300);
-
print100(i+400);
-
print100(i+500);
-
print100(i+600);
-
print100(i+700);
-
print100(i+800);
-
print100(i+900);
-
}
-
-
int main() {
-
print1000(1);
-
return 0;
-
}
不过,print用得多了一些。我们可以用宏嘛。
- #include<stdio.h>
-
#define Out(i) printf("%d\n", i++);
-
#define REP(N) N N N N N N N N N N
-
#define Out1000(i) REP(REP(REP(Out(i))));
-
void main()
-
{
-
int i = 1;
-
Out1000(i);
不过,我们应该使用C++的一些特性,比如:
使用构造函数
- class Printer
-
{
-
public:
-
Printer() { static unsigned i=1; cout << i++ << endl;; }
-
-
};
-
-
int main()
-
{
-
Printer p[1000];
-
}
或是更为NB的Template:
- template<int N>
-
struct NumberGeneration{
-
static void out(std::ostream& os)
-
{
-
NumberGeneration<N-1>::out(os);
-
os << N << std::endl;
-
}
-
};
-
-
template<>
-
struct NumberGeneration<1>{
-
static void out(std::ostream& os)
-
{
-
os << 1 << std::endl;
-
}
-
};
-
-
int main(){
-
NumberGeneration<1000>::out(std::cout);
-
}
最后来个BT一点的:
#include
#include
void main(int j) { printf("%d\n", j); (main + (exit - main)*(j/1000))(j+1); }
|
分析一下这个BT函数,其实还好,比较好理解,关键是(main + (exit - main)*(j/1000))(j+1)这个地方,
我们知道程序里面main 或者exit或者其他的函数,都是一个别名,指向函数实际的内存地址。
(f)(arglist)就能调用带参数列表arglist的函数f了。
在上面,main + (exit - main)*(j/1000)其实在j<1000时,为main+(exit-main)*0=main,调用main(j+1)。
当j=1000时,调用的是main + (exit-main)*1 = exit这个函数,然后就退出了。
原来main也可以调用自己,写了一个测试小程序^_^
- #include <stdlib.h>
-
#include <stdio.h>
-
-
typedef void(*p2Foo)(int) ;
-
-
void prt(int a)
-
{
-
printf("int prt ^_^ %d\n",a);
-
}
-
-
p2Foo p2f = prt;
-
-
void main(int argc )
-
{
-
printf("%d\n",argc);
-
//printf("main %d p2f %d next %d and arg is %d \n", main, p2f, main+(p2f - main)*(argc/100),argc+1);
-
(main+(p2f - main)*(argc/100))(argc+1);
-
printf("ends with argc %d \n", argc);
-
}
参考:来源:
Insert mode
阅读(1778) | 评论(0) | 转发(0) |