来源:伯乐在线 - 伯小乐
链接:http://group.jobbole.com/22100/
在 Quora 上看到有个程序员的提问:
如果不用循环、递归、goto,我如何才能用 C++ 从 1 打印到 100 ?
原题主问的是用 C++ 来实现。
【2016-08-10 更新】:补充国外程序员的一些方案:
Mark Gordon, ICPC 2011 Gold Medalist (msg555)
第一种:
#include <stdlib.h>
intmain(){
/* Cross your fingers and hope seq exists! */
returnsystem("seq 1 100");
}
第二种:下面这个方案在我电脑上没问题,但不保证你们电脑上也OK
#include <iostream>
#include <stdlib.h>
intnum;
void(**rptr)();
voidfoo(){
if(num >= 100)exit(0);
std::cout << ++num << std::endl;
*rptr++ = foo;
}
intmain(){
rptr = (void(**)())alloca(sizeof(*rptr) * 200) - 1;
foo();
return0;
}
第三种:
#include <iostream>
#include <stdlib.h>
intmain(){
intx = 0;
x |= !fork() << 0;
x |= !fork() << 1;
x |= !fork() << 2;
x |= !fork() << 3;
x |= !fork() << 4;
x |= !fork() << 5;
x |= !fork() << 6;
if(1 <= x && x <= 100)std::cout << x << std::endl;
return0;
}
第四种:similar to bashing templates you can bash the preprocessor
#include <stdio.h>
#define F4 "%dn%dn%dn%dn"
#define F20 F4 F4 F4 F4 F4
#define F100 F20 F20 F20 F20 F20
#define X4(y) , y, y + 1, y + 2, y + 3
#define X20(y) X4(y) X4(y + 4) X4(y + 8) X4(y + 12) X4(y + 16)
#define X100(y) X20(y) X20(y + 20) X20(y + 40) X20(y + 60) X20(y + 80)
intmain(){
printf(F100 X100(1));
return0;
}
第五种:Advanced preprocessor bashing
#if (__COUNTER__ == 0)
#include <stdio.h>
intmain(){
#include __FILE__
return0;
}
#elif (__COUNTER__ < 300)
printf("%dn",__COUNTER__ / 3);
#include __FILE__
#endif
Divye Kapoor 的补充:
Mark Gordon 给出了一些非常好的方案,我也来补充一些
第六种:Using the alarm system call.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
inti = 0;
voidsig_alarm_handler(intsignal){
++i;
printf("%dn",i);
if(i < 100)
alarm(1);
else
exit(0);
}
intmain(){
signal(SIGALRM,sig_alarm_handler);
alarm(1);
intx;
scanf(" %d",&x);
return0;
}
第七种:Using fread and fwrite
#include <stdlib.h>
#include <stdio.h>
intmain(){
FILE*fd = fopen("data.txt","r");
charbuf[10000];
size_tn = fread(buf,sizeof(char),10000,fd);
fwrite(buf,sizeof(char),n,stdout);
fflush(stdout);
fclose(fd);
return0;
}
第八种:Using queued SIGUSR calls
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
intmypid;
voidsignal_handler(intsignal,siginfo_t*siginfo,void*extra){
printf("%dn",siginfo->si_int);
sigval_tsignal_value;
memcpy(&signal_value,&siginfo->si_value,sizeof(signal_value));
++signal_value.sival_int;
if(signal_value.sival_int <= 100)
sigqueue(mypid,SIGUSR1,signal_value);
else
exit(0);
}
intmain(){
mypid = getpid();
structsigactionsa;
bzero(&sa,sizeof(sa));
sa.sa_sigaction = signal_handler;
sa.sa_flags = SA_SIGINFO | SA_NODEFER | SA_RESTART;
sigaction(SIGUSR1,&sa,NULL);
sigval_tsignal_value;
signal_value.sival_int = 1;
sigqueue(mypid,SIGUSR1,signal_value);
sleep(1000);
return0;
}
第九种:Memory mapping a file
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
intmain(){
intfd = open("data.txt",O_RDONLY);
structstatstat_data;
fstat(fd,&stat_data);
off_tfile_size = stat_data.st_size;
// Memory map the file
void*baseaddr = mmap(NULL,file_size,PROT_READ,MAP_PRIVATE,fd,0);
// Copy the memory mapped region to stdout
fwrite((char*)baseaddr,sizeof(char),file_size,stdout);
fflush(stdout);
// Unmap the memory mapped region
munmap(baseaddr,file_size);
// Close the file
close(fd);
return0;
}
下面这这些,我看其他网友也有提到,但发现可以优化一下
第十种:The standard template metaprogram
#include <stdio.h>
template<intN>
structX : X<N-1>{
X(){printf("%dn",N);}
};
template<>
structX<0>{};
intmain(){
X<100>x;
return0;
}
第十一:用静态变量和数组
#include <stdio.h>
structX{
staticinti;
X(){ ++i;printf("%dn",i);}
};
intX::i = 0;
intmain(){
Xarr[100];
return0;
}