C编译器如何在递归期间处理堆栈中的局部变量?

时间:2011-11-28 16:52:02

标签: c recursion stack

我编写了一个简单的二进制搜索程序并遇到问题,请参阅下面的三个混淆:

  • 如果我选择icc -g main.cicc -O0 main.c,则代码会返回错误答案,但如果我使用icc -O2 main.c,我可以得到正确答案。

  • mid = (beg + end) / 2;之前定义代码if(beg <= end) {,无论我使用什么标志编译它,答案都是正确的。

  • 我认为问题是递归过程中堆栈中的局部变量mid

帮助我,谢谢!

#include <stdio.h>
#define MAX 6
int a[MAX] = {1,2,3,4,5,6};
int improved_binary_search(int key, int beg, int end) {
    int mid, temp;
    //mid = (beg + end) / 2;
    if(beg <= end) {
             mid = (beg + end ) /2;
             if(a[mid] == key)
                     return mid;
             if(a[mid] < key)
                     return improved_binary_search(key, mid + 1, end);
              if(a[mid] > key)
                      return improved_binary_search(key, beg, mid - 1);
              //printf("test is %d\n", mid);
      }
      if(mid == 0)
              return 0;
      if(mid == MAX - 1)
              return MAX - 1;
      if(a[mid] < key)
              return a[mid+1] - key < key - a[mid] ? mid+1 : mid;
      if(a[mid] > key)
              return a[mid] - key < key - a[mid-1] ? mid : mid-1;
      return -1;
  }

int main(void)
{
     printf("%d\n", improved_binary_search(100, 0, MAX - 1));
     return 0;
}

2 个答案:

答案 0 :(得分:5)

您刚刚宣布mid但未对其进行初始化,可能会发生如果第一个if条件(if(beg <= end))未被点击,则mid的值为不确定即可。

这将导致未定义的行为。您看到的行为是因为这个UB而不是因为编译器配置。

您应始终将变量初始化为有意义的值。

答案 1 :(得分:2)

一个问题是,除非mid,否则您不会初始化beg <= end。然后在improved_binary_search()的后半部分使用(可能未初始化的)变量。这是未定义的行为。

要修复,请务必始终初始化mid