【问题标题】:Why Output is 0000 and How? [duplicate]为什么输出是 0000 以及如何? [复制]
【发布时间】:2013-11-10 14:32:40
【问题描述】:

我执行了这个程序,但无法理解为什么输出为“0”四次。谁能帮我理解它是如何工作的?我不明白为什么“printf”在条件失败时会执行,为什么会执行四次。

int main() 
{
    static int i=5; 
    if(--i)
    {
        main(); 
        printf("%d ",i);
    }
}

【问题讨论】:

标签: c


【解决方案1】:

您的 main 函数打印 4 次 0,因为 printf 语句发生在递归调用之后,而 i 是一个静态变量。静态变量只初始化一次,并且在函数终止后不会被销毁,因为它没有分配到函数堆栈中。
结果,printf 使用的 i 的值始终为 0,因为每次调用 main 时,i 都会递减,并且在最深的函数返回后执行第一个 printf 函数,因为 i=0 .

为了更好地理解这个解决方案,让我们看一下堆栈调用:

main() i=5 (First call)  
      if(4) // True
      main() (Second call) 
        if(3) // True
        main() (Third  call)
          if(2) // True
            main() (Forth call) 
               if(1) // True
                 main() (Fifth call)
                    if(0) //False End recursion No print because the condition is false
                 return
                print(i) // 0 (Forth Call)
            print(i) // 0 (Third  call)
         printf(i) // 0  (Second call) 
      print(i) // 0 (First call) 

main 被调用了 5 次,但应用程序打印了 4 个零,因为最后一次调用没有打印任何内容,因为 if 条件为假。

【讨论】:

  • 我理解 i 是静态的,所以它在程序中初始化了一次,但每次 main() 在 printf 之前调用并且在最后一个条件为假,所以我们不会进入 if 块 那么 printf 是如何执行?
  • 我已经更新了我的答案。让我知道现在是否更清楚
  • 是的,谢谢先生,但是如果我们删除静态关键字,那么为什么它会变成无限意味着 Stackoverflow 调用,如果我们只删除静态关键字,那么它应该打印 1234
  • 如果你从 i 中删除 static,函数永远不会到达递归的末尾,因为对于每个函数调用 i=5,因此 if 始终为 true,而对 main 的另一个调用是制作。
  • 哦,我忘记了静态属性。好的,谢谢
【解决方案2】:

istatic 所以它只被初始化一次。每次调用 main 时它都会减少,当 i == 1 时,`if 语句条件将在此处为 false

if(--i)

递归将停止,i 将变为 0,然后递归将展开,程序将打印四个 0s。

为了完整起见,草案 C99 标准部分 6.2.4对象的存储持续时间3 段说(强调我的): p>

一个对象,其标识符是用外部或内部链接声明的,或者用 storage-class specifier static 具有静态存储持续时间。它的生命周期是整个 程序的执行及其存储的值仅在程序之前初始化一次 启动

【讨论】:

  • 我理解我是静态的,所以它在程序中初始化了一次,但我仍然无法理解 printf 没有机会执行它仍然打印值如何?
  • @RaaJivYadav 在每个 printf 之前都有一个对 main 的递归调用,因此在递归结束之前不会到达第一个 printf,这将在 i == 1 时发生。跨度>
  • 是的,在 printf 之前有对 main 的递归调用,因此控制将到达 main 然后再次它将进入 if 条件然后再次控制将在 printf 之前到达 main 并且当 i==1 然后 if(- -i) 看起来像 if(0) 然后控制不会进入 if 条件并且程序将结束 那么如何执行 printf
  • @RaaJivYadav 当代码脱离main 的末尾时,它将返回到main 的先前调用并继续执行它在printf 之前的中断处,它将在这种情况下为每个递归级别执行此操作 4 级别。
猜你喜欢
  • 2021-07-29
  • 2022-12-13
  • 2016-11-11
  • 1970-01-01
  • 2012-03-06
  • 2019-11-15
  • 1970-01-01
  • 2012-02-16
  • 1970-01-01
相关资源
最近更新 更多