评论如何改变程序的输出?

时间:2015-09-05 14:42:20

标签: c

我只是C语言的新手。我正在使用code6.4进行C. 请参阅后面的代码。

int main(int argc, const char * argv[]) {
    int a[5]={1,4,7,3,5};

    merge(a, 0, 2, 4);
    printf("%d",a[4]);

    return 0;
}

void merge(int *a ,int p ,int q,int r){
    int n1,n2;
    n1=q-p+1;
    n2=r-q;
    int temp1[n1];
    int temp2[n2];
    int i,j,k;
    for (i=0; i<n1; i++) {
        temp1[i]=a[p+i];
    }
    for (i=0; i<n2; i++) {
        temp2[i]=a[q+1+i];
    }
    j=0;
    k=0;
    for (i=p; i<=r; i++) {
        if (temp1[j]<temp2[k]) {
            a[i]=temp1[j];
            j++;
        }
        else{
            a[i]=temp2[k];
            k++;
        }
    }
    printf("%d ",a[4]);
}

所以输出是:

  

7 7

我上传了截屏。

http://i.stack.imgur.com/AfhFD.png

但是当我评论第二个printf时:

 for (i=p; i<=r; i++) {
    if (temp1[j]<temp2[k]) {
        a[i]=temp1[j];
        j++;
    }
    else{
        a[i]=temp2[k];
        k++;
    }
 }
 //printf("%d ",a[4]);

第一个printf的输出已更改。如下图所示。

  

-1231562870

http://i.stack.imgur.com/9NPlw.png

我知道这可能很荒谬,但是有人可以帮助我吗?

1 个答案:

答案 0 :(得分:2)

您的程序在此处调用未定义的行为:

if (temp1[j]<temp2[k]) { ... }

在您的具体示例中,它会在i == r时发生,因为您将temp1[2]temp2[2]进行比较,但temp2仅包含2个元素,因此这是一个边界访问。

试图用UB推理程序是不受欢迎的;修复错误,这应该可以阻止你有其他意外。

一种可能的解决方法是将最后一个循环更改为:

for (i=p; i<=r; i++) {
    if (k < n2 && j < n1) {
        if (temp1[j] < temp2[k]) {
            a[i] = temp1[j];
            j++;
        } else {
            a[i] = temp2[k];
            k++;
        }
    } else if (k < n2) {
        a[i] = temp2[k];
        k++;
    } else {
        a[i] = temp1[j];
        j++;
    }
}