在c编程中,如何在不使用循环、递归或goto语句的情况下打印1到100?
我从互联网上找到了这个解决方案在c编程中,如何在不使用循环、递归或goto语句的情况下打印1到100?,c,algorithm,C,Algorithm,我从互联网上找到了这个解决方案 #include <stdio.h> #include <stdlib.h> int n = 0; void first() { void* x; printf("%d\n", ++n); if (n >= 100) { exit(0); } *((char**) (&x + 4)) -= 5; } int main() { first(); ret
#include <stdio.h>
#include <stdlib.h>
int n = 0;
void first() {
void* x;
printf("%d\n", ++n);
if (n >= 100) {
exit(0);
}
*((char**) (&x + 4)) -= 5;
}
int main() {
first();
return 1;
}
#包括
#包括
int n=0;
首先无效(){
void*x;
printf(“%d\n”,++n);
如果(n>=100){
出口(0);
}
*((字符**)(&x+4))-=5;
}
int main(){
第一个();
返回1;
}
有人能给我解释一下这行的意思吗代码> 这个练习毫无意义。这就是说,您的“黑客”似乎试图模拟
setjmp/longjmp
的行为,它存储/恢复执行环境的状态,例如程序计数器
// Silly code to solve artificial problems. Don't write programs like this.
#include <stdio.h>
#include <setjmp.h>
void silly_print (int max)
{
jmp_buf jb;
int n = setjmp(jb);
printf("%d\n", ++n);
if(n < max)
{
longjmp(jb, n);
}
}
int main()
{
silly_print(100);
}
//解决人工问题的愚蠢代码。不要这样写程序。
#包括
#包括
无效打印(整数最大值)
{
jmp_buf jb;
int n=setjmp(jb);
printf(“%d\n”,++n);
如果(n
注意:
setjmp/longjmp
被认为是危险的,因为它们可能会导致各种意外的副作用。它们也被认为是不好的做法,因为它们可以用于意大利面条编程,正如上面代码中所做的那样,这实际上是未定义的行为。它使用编译器和硬件平台的堆栈布局知识,并修改函数返回地址,以便在第一次返回时返回自身。除非您拥有该程序设计的确切CPU和编译器版本,否则很可能会发生崩溃。如果操作系统有某种破坏堆栈的保护,您可能会得到这样的结果。它肯定不会在具有64位指针的系统上工作。***((char**)(&x+4))-=5**代码>--此行不编译printf(“12345…”)
-愚蠢的练习需要愚蠢的解决方案。printf(“1到100”)代码>可能我无法回答,因为这个问题已关闭,但您可以使用宏:#define REP10(x)x;x;x;x;x;x;x;x;x;x代码>
#定义REP100(x)REP10(REP10(x))
然后在主int i=0;REP100(printf(“%d\n”,++i))
所以,这是伪装的GOTO。@rishikshraje确切地说是非本地go-to。它允许您从当前函数直接跳出到另一个函数。@rishikshraje实际上不是<代码>转到
转换为无条件分支指令。setjmp/longjmp转换为存储/恢复杂项系统变量。它更像是伪装的内联汇编程序。@Lundin如果我理解正确,GOTO会影响程序计数器,而longjmp会影响堆栈指针、帧指针和程序计数器。@rishikshraje所有条件代码都会导致分支,因此会影响程序计数器<代码>转到
当然也不例外,它影响程序计数器,就像如果
、为
或执行时一样。没有指定sepjmp/longjmp会影响什么,但它确实似乎以某种方式存储了堆栈/数据寄存器的当前状态,以及程序计数器和可能的条件代码寄存器。我必须承认,我从来没有费心去分解setjmp/longjmp来看看,因为我根本不打算使用这些函数。