2015-10-22 3 views
0

Итак, я собрал эти два алгоритма:Странное поведение в C

int digitCount(int num){ 
    int count; 
    while (num) { 
     num /= 10; 
     count++; 
    } 
    return count; 
} 

int digitSplit(int num, int digit) { 
    int i, base = 1, count = digitCount(num); 
    for(i = 1; i <= count + 1 - digit; i++) 
     base *= 10; 
    return num % base/(base/10); 
} 

Хотя я понимаю, что они не могут быть оптимальными, то digitSplit дает мне очень странное поведение:

for (i = 1; i < 4; i++) 
    printf("%d", digitSplit(432, i)); 

Этот один всегда сбой, независимо от настройки.

printf("%d, %d, %d", digitSplit(432, 1), digitSplit(432, 2), digitSplit(432, 3)); 

Это один тушит 0, 0, 2.

printf("%d", digitSplit(432, 1)); 
printf("%d", digitSplit(432, 2)); 
printf("%d", digitSplit(432, 3)); 

Они потушить 4 3 2 запустить отдельно, в противном случае они сбою программы =>for -loop.

Не знаю, почему это происходит, очевидно, что мой digitSplit является причиной, но как возникают 0, 0, 2?

+7

'digitCount' должен инициализировать' count' до нуля. – keithmo

+4

'num% base/(base/10)' такое же, как 'num% base/(1/10)' то же, что 'num% base/(0)' kaboom division на 0! – ouah

+2

Я предлагаю вам проверять предупреждения компилятора. – juanchopanza

ответ

1

Некоторые проблемы, которые могут возникнуть в C: Если вы не инициализируете переменную, она имеет значение последнего изменения этого бита памяти. Это всегда хорошая форма, чтобы инициализировать переменные со значением, но в C это дополнительный важно:

int digitCount(int num){ 
    int count = 0; 
    while (num) { 
     num /= 10; 
     count++; 
    } 
    return count; 
} 

То, что вы возвращаетесь в digitSplit() не является правильным. Вы хотите перенести определенную цифру так, чтобы она находилась на месте, а затем изолировать цифру с помощью mod 10. Сначала мы должны перенести цифру, которую мы хотим, на место, разделив num на 10^(количество цифр) , а не 10^(счет + 1-значный). Пусть 10^(count-digit) = base, поэтому мы имеем (num/base). Теперь нам нужно только получить свое место. Мы делаем это с mod:

int digitSplit(int num, int digit) { 
    int i, base = 1, count = digitCount(num); 
    for(i = 1; i <= count - digit; i++) 
     base *= 10; 
    return (num/base)%10; 
} 
+0

" он имеет значение того, что последний изменил этот бит памяти »- вот что может показаться, но не является частью спецификации языка. Формально он имеет * неопределенное значение *, и они могут вести себя по-разному. Например, 'count-count' может не дать' 0', или компилятор может даже оптимизировать все это. –

+0

Благодарю вас за подробный ответ, вот и все. моя функция возвращает правильные значения, но я могу видеть, как ваш расчет лучше! – Carl

Смежные вопросы