任务:打印从1到1000的数字,不使用任何循环或条件语句。不要只写printf()或cout语句1000次。
用C或c++怎么做呢?
任务:打印从1到1000的数字,不使用任何循环或条件语句。不要只写printf()或cout语句1000次。
用C或c++怎么做呢?
当前回答
使用指针算术,我们可以将数组自动初始化为0。
#include <stdio.h>
void func();
typedef void (*fpa)();
fpa fparray[1002] = { 0 };
int x = 1;
void func() {
printf("%i\n", x++);
((long)fparray[x] + &func)();
}
void end() { return; }
int main() {
fparray[1001] = (fpa)(&end - &func);
func();
return 0;
}
其他回答
下面是使用信号的POSIX变体:
#include <stdio.h>
#include <signal.h>
void counter(int done)
{
static int i;
done = ++i / 1000;
printf("%d\n", i);
signal(SIGINT, (void (*)(int))(done * (int)SIG_DFL + (1-done) * (int)&counter));
raise(SIGINT);
}
int main()
{
signal(SIGINT, &counter);
raise(SIGINT);
return 0;
}
有趣的部分是counter()对signal()的调用。在这里,将安装一个新的信号处理程序:如果"done"为真,则SIG_DFL,否则计数器。
为了使这个解决方案更加可笑,我使用了信号处理程序所需的int形参来保存临时计算的结果。作为一个副作用,恼人的“未使用变量”警告在使用gcc -W -Wall编译时消失。
有趣的函数指针(不需要新流行的TMP):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#define MSB(typ) ((sizeof(typ) * CHAR_BIT) - 1)
void done(int x, int y);
void display(int x, int y);
void (*funcs[])(int,int) = {
done,
display
};
void done(int x, int y)
{
exit(0);
}
void display(int x, int limit)
{
printf( "%d\n", x);
funcs[(((unsigned int)(x-limit)) >> MSB(int)) & 1](x+1, limit);
}
int main()
{
display(1, 1000);
return 0;
}
附注:我将禁止条件符扩展到逻辑运算符和关系运算符。如果允许逻辑否定,递归调用可以简化为:
funcs[!!(limit-1)](x+1, limit-1);
#include <stdio.h>
int main(int argc, char** argv)
{
printf("numbers from 1 to 1000\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);
}
到目前为止,由于堆栈溢出,有很多不正常的退出,但还没有堆,所以这里是我的贡献:
#include <cstdio>
#include <cstdlib>
#include <sys/mman.h>
#include <sys/signal.h>
#define PAGE_SIZE 4096
void print_and_set(int i, int* s)
{
*s = i;
printf("%d\n", i);
print_and_set(i + 1, s + 1);
}
void
sigsegv(int)
{
fflush(stdout); exit(0);
}
int
main(int argc, char** argv)
{
int* mem = reinterpret_cast<int*>
(reinterpret_cast<char*>(mmap(NULL, PAGE_SIZE * 2, PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, 0, 0)) +
PAGE_SIZE - 1000 * sizeof(int));
mprotect(mem + 1000, PAGE_SIZE, PROT_NONE);
signal(SIGSEGV, sigsegv);
print_and_set(1, mem);
}
这不是很好的实践,也没有错误检查(原因很明显),但我不认为这是问题的重点!
当然,还有许多其他不正常的终止选项,其中一些更简单:assert()、SIGFPE(我认为有人这样做了),等等。