Один и тот же код возвращает разные значения в компиляторе gcc и Turbo C - PullRequest
0 голосов
/ 24 февраля 2012

При выполнении приведенного ниже кода для размера массива 2 с 2 одинаковыми элементами скажем 11,11 оба компилятора возвращают правильную верхнюю и нижнюю границу массива.Но при выполнении того же для (1,1), gcc возвращает -1 (число не в массиве) для верхней границы, тогда как турбо C возвращает 1 для того же.

int binarylower(int a[],int m,int l,int u,int uorl)
{
    int mid;

    if(l<=u)
    {   //finds the mid position
        mid=(l+u)/2;
        if (uorl == 1)
        {
            if(m==a[mid])
            {
                if ((m != a[mid-1])|| (mid == 0 && m==a[mid]))
                {
                    return mid;
                }
                else
                {
                    return binarylower(a,m,l,mid-1,1);
                }
            }
            else if(m<a[mid])
            {
                return binarylower(a,m,l,mid-1,1);
            }
            else 
            {
                return binarylower(a,m,mid+1,u,1);
            }
        }
        else if(uorl == 2)
        {
            if(m==a[mid])
            {            
                if ((m != a[mid+1]))
                {
                    return mid;
                    }
                    else
                    {
                    return binarylower(a,m,mid+1,u,2);
                    }
            }           
            else if(m < a[mid])
            {           
                return binarylower(a,m,l,mid-1,2);
            }           
            else
            {
                return binarylower(a,m,mid+1,u,2);
            }
        }
    }
    else
    {
        return -1;
    }
}

1 Ответ

0 голосов
/ 24 февраля 2012

В коде скрывается проблема

Одно из ваших условий:

if ((m != a[mid-1]) || (mid == 0 && m == a[mid]))

Это не гарантирует, что mid-1 находится в диапазоне. Соответствующее условие в другой ветви не проверяет, что mid+1 находится в диапазоне. Итак, ваш код перемещается по частям массива, на которые он не имеет права смотреть, что приводит к неопределенному поведению.


Тестирование может показать только наличие ошибок, но не их отсутствие!

Дейкстра сказал это очень мудро.

Я добавил:

  1. else return -1; после else if (uorl == 2) для предотвращения предупреждения компилятором о функции, не возвращающей значение.

  2. Испытательный жгут:

    #include <stdio.h>
    
    int main(void)
    {
        int array[] = { 11, 11 };
        printf("%d\n", binarylower(array, 11, 0, 1, 1));
        printf("%d\n", binarylower(array, 11, 0, 1, 2));
        return 0;
    }
    

С GCC в Mac OS X, который выдает 0 и 1 в качестве ответов, что кажется разумным и правильным. Как выглядел ваш тестовый комплект?

Более обширный тестовый жгут:

#include <stdio.h>

int main(void)
{
    int array[] = { 11, 11 };
    printf("Array[0] = %d, [1] = %d\n", array[0], array[1]);
    printf("%d Lo: %d\n", 10, binarylower(array, 10, 0, 1, 1));
    printf("%d Hi: %d\n", 10, binarylower(array, 10, 0, 1, 2));
    printf("%d Lo: %d\n", 11, binarylower(array, 11, 0, 1, 1));
    printf("%d Hi: %d\n", 11, binarylower(array, 11, 0, 1, 2));
    printf("%d Lo: %d\n", 12, binarylower(array, 12, 0, 1, 1));
    printf("%d Hi: %d\n", 12, binarylower(array, 12, 0, 1, 2));

    array[1] = 13;
    printf("Array[0] = %d, [1] = %d\n", array[0], array[1]);
    printf("%d Lo: %d\n", 10, binarylower(array, 10, 0, 1, 1));
    printf("%d Hi: %d\n", 10, binarylower(array, 10, 0, 1, 2));
    printf("%d Lo: %d\n", 11, binarylower(array, 11, 0, 1, 1));
    printf("%d Hi: %d\n", 11, binarylower(array, 11, 0, 1, 2));
    printf("%d Lo: %d\n", 12, binarylower(array, 12, 0, 1, 1));
    printf("%d Hi: %d\n", 12, binarylower(array, 12, 0, 1, 2));
    printf("%d Lo: %d\n", 13, binarylower(array, 13, 0, 1, 1));
    printf("%d Hi: %d\n", 13, binarylower(array, 13, 0, 1, 2));
    printf("%d Lo: %d\n", 14, binarylower(array, 14, 0, 1, 1));
    printf("%d Hi: %d\n", 14, binarylower(array, 14, 0, 1, 2));

    return 0;
}

Выход из этого:

Array[0] = 11, [1] = 11
10 Lo: -1
10 Hi: -1
11 Lo: 0
11 Hi: 1
12 Lo: -1
12 Hi: -1
Array[0] = 11, [1] = 13
10 Lo: -1
10 Hi: -1
11 Lo: 0
11 Hi: 0
12 Lo: -1
12 Hi: -1
13 Lo: 1
13 Hi: 1
14 Lo: -1
14 Hi: -1

Это выглядит безупречно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...