这段代码如何在C中打印一系列数字?
这是一个基本的C程序,它不使用循环或条件来打印数字。我想知道它是如何做到的,以及“退出”和“主要”的目的。这里的这段代码如何在C中打印一系列数字?,c,C,这是一个基本的C程序,它不使用循环或条件来打印数字。我想知道它是如何做到的,以及“退出”和“主要”的目的。这里的main用于递归吗 #include <stdio.h> #include <stdlib.h> void main(int j) { printf("%d\n", j); (&main + (&exit - &main)*(j/1000))(j+1); } #包括 #包括 真空总管(int j){ printf(“%
main
用于递归吗
#include <stdio.h>
#include <stdlib.h>
void main(int j) {
printf("%d\n", j);
(&main + (&exit - &main)*(j/1000))(j+1);
}
#包括
#包括
真空总管(int j){
printf(“%d\n”,j);
(&main+(&exit-&main)*(j/1000))(j+1);
}
假设j是500。然后(&exit-&main)
是某种东西(不管是什么),而(j/1000)
是0,所以(&main+(&exit-&main)*(j/1000))(j+1)
实际上是main(501)
。相反,如果j是1000,那么(j/1000)
是1,这意味着(&main+(&exit-&main)*(j/1000))
与(&main+(&exit-&main))
(也就是说,&exit
)相同,因此它调用退出(1001)
。假设j是500。然后(&exit-&main)
是某种东西(不管是什么),而(j/1000)
是0,所以(&main+(&exit-&main)*(j/1000))(j+1)
实际上是main(501)
。相反,如果j是1000,那么(j/1000)
是1,这意味着(&main+(&exit-&main)*(j/1000))
与(&main+(&exit-&main))
(也就是说,&exit
)相同,因此它调用退出(1001)
。我建议它的工作方式如下:
- 当
时,使用参数j<1000
调用j+1
。由于&main+(&exit-&main)*(j/1000)
,它调用j/1000==0
main(j+1)
- 当
时,由于j=1000
,它调用j/1000==1
=&main+(&exit-&main)*1
exit
然而,在这个小小的C程序中有很多错误。例如,
void main(int)
不是标准的main
签名。我建议它的工作原理如下:
- 当
时,使用参数j<1000
调用j+1
。由于&main+(&exit-&main)*(j/1000)
,它调用j/1000==0
main(j+1)
- 当
时,由于j=1000
,它调用j/1000==1
=&main+(&exit-&main)*1
exit
然而,在这个小小的C程序中有很多错误。例如,
void main(int)
不是标准的main
签名。此签名实际上编译到没有任何条件的程序集:
#include <stdio.h>
#include <stdlib.h>
void main(int j) {
printf("%d\n", j);
(&main + (&exit - &main)*(j/1000))(j+1);
}
#包括
#包括
真空总管(int j){
printf(“%d\n”,j);
(&main+(&exit-&main)*(j/1000))(j+1);
}
尝试:添加“&”,因此它会考虑地址,从而躲避指针错误。
上述版本采用标准C,因为它不依赖函数指针上的算术运算:#include <stdio.h>
#include <stdlib.h>
void f(int j)
{
static void (*const ft[2])(int) = { f, exit };
printf("%d\n", j);
ft[j/1000](j + 1);
}
int main(int argc, char *argv[])
{
f(1);
}
#包括
#包括
空f(int j)
{
静态void(*const ft[2])(int)={f,exit};
printf(“%d\n”,j);
英尺[j/1000](j+1);
}
int main(int argc,char*argv[])
{
f(1);
}
这一个实际上编译为没有任何条件的程序集:
#include <stdio.h>
#include <stdlib.h>
void main(int j) {
printf("%d\n", j);
(&main + (&exit - &main)*(j/1000))(j+1);
}
#包括
#包括
真空总管(int j){
printf(“%d\n”,j);
(&main+(&exit-&main)*(j/1000))(j+1);
}
尝试:添加“&”,因此它会考虑地址,从而躲避指针错误。
上述版本采用标准C,因为它不依赖函数指针上的算术运算:#include <stdio.h>
#include <stdlib.h>
void f(int j)
{
static void (*const ft[2])(int) = { f, exit };
printf("%d\n", j);
ft[j/1000](j + 1);
}
int main(int argc, char *argv[])
{
f(1);
}
#包括
#包括
空f(int j)
{
静态void(*const ft[2])(int)={f,exit};
printf(“%d\n”,j);
英尺[j/1000](j+1);
}
int main(int argc,char*argv[])
{
f(1);
}
- &main是主函数的地址(任何C的入口点 计划)
- &exit是函数的地址(终止程序)
(&main + (&exit - &main)*(j/1000))(j+1);
if j < 1000, then
(&exit - &main)*(j/1000) == 0 (integers division)
// So we are calling main(j+1)
else if j == 1000
(&exit - &main)*(j/1000) == &exit - &main
// So we are calling (&main + &exit - &main)(j+1), which is calling exit(j+1)
(&main+(&exit-&main)*(j/1000))(j+1);
如果j<1000,则
(&exit-&main)*(j/1000)==0(整数除法)
//所以我们调用main(j+1)
否则,如果j==1000
(&exit-&main)*(j/1000)==&exit-&main
//所以我们调用(&main+&exit-&main)(j+1),这就是调用exit(j+1)
因此,您的程序递归调用main(),直到j==1000,此时它调用exit
这个程序在编程/最佳实践等方面是错误的,你应该忘记它。- &main是主函数的地址(任何C的入口点 计划)
- &exit是函数的地址(终止程序)
(&main + (&exit - &main)*(j/1000))(j+1);
if j < 1000, then
(&exit - &main)*(j/1000) == 0 (integers division)
// So we are calling main(j+1)
else if j == 1000
(&exit - &main)*(j/1000) == &exit - &main
// So we are calling (&main + &exit - &main)(j+1), which is calling exit(j+1)
(&main+(&exit-&main)*(j/1000))(j+1);
如果j<1000,则
(&exit-&main)*(j/1000)==0(整数除法)
//所以我们调用main(j+1)
否则,如果j==1000
(&exit-&main)*(j/1000)==&exit-&main
//所以我们调用(&main+&exit-&main)(j+1),这就是调用exit(j+1)
因此,您的程序递归调用main(),直到j==1000,此时它调用exit
这个程序在编程/最佳实践等方面是如此错误,你应该忘记它。这在许多方面是一个基本错误,C程序使用递归和
main
函数…它使用了一个可怕的基于指针的递归。所以没有循环,但是对main()的许多隐藏在普通视图中的调用是非常酷的递归版本。乘法就像一个比较,如果j为1000,则会重定向到退出函数。标准C中此代码的确切问题是它违反了约束,因为-
和+
不能与函数指针一起使用。当然,它的实现定义为是否允许main
的签名。这可能是一个基本错误,在许多方面,C程序使用递归和main
函数…它使用了一个可怕的基于指针的递归。所以没有循环,但是对main()的许多隐藏在普通视图中的调用是非常酷的递归版本。乘法就像一个比较