这段代码如何在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(“%

这是一个基本的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(“%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()的许多隐藏在普通视图中的调用是非常酷的递归版本。乘法就像一个比较