Rowan Kasim Ответов: 4

Plz помогите мне определить ошибку, которую я сделал в этом кодировании proram


#include <stdio.h>
int factorial(int i);

int factorial(int i){
    int x;
    for(x=1;x<i;x++){
        i=i*x;
    }
    return i;
}

int main(){
    int a;
    a=factorial(5)+10;
    printf("%d\n",a);
    0;
}


Что я уже пробовал:

Я пробовал много раз, логика кажется правильной, но код не получает правильного ответа

Rick York

Слово-пожалуйста.

Stefan_Lang

Вообще-то это "пожалуйста". Кричать было бы неуместно ;-)

4 Ответов

Рейтинг:
32

Patrice T

int factorial(int i){
    int x;
    for(x=1;x<i;x++){ // i is the limit to end of loop
        i=i*x; // but here you change i
    }
    return i;
}

Цитата:
Plz помогите мне определить ошибку, которую я сделал в этом кодировании proram

Ваш код ведет себя не так, как вы ожидаете, или вы не понимаете, почему !

Существует почти универсальное решение: запускайте свой код на отладчике шаг за шагом, проверяйте переменные.
Отладчик здесь, чтобы показать вам, что делает ваш код, и ваша задача-сравнить с тем, что он должен делать.
В отладчике нет никакой магии, он не знает, что должен делать ваш код, он не находит ошибок, он просто помогает вам, показывая, что происходит. Когда код не делает того, что ожидается, вы близки к ошибке.
Чтобы увидеть, что делает ваш код: просто установите точку останова и посмотрите, как работает ваш код, отладчик позволит вам выполнять строки 1 на 1 и проверять переменные по мере их выполнения.

Отладчик - Википедия, свободная энциклопедия[^]

Освоение отладки в Visual Studio 2010 - руководство для начинающих[^]
Базовая отладка с помощью Visual Studio 2010 - YouTube[^]

1.11 — отладка программы (пошаговое выполнение и останова) | выучить C++[^]

Отладчик здесь только для того, чтобы показать вам, что делает ваш код, и ваша задача-сравнить его с тем, что он должен делать.


CPallini

5.

Patrice T

Спасибо

Рейтинг:
21

Richard Deeming

Каждый раз через ваш for цикл, вы увеличиваете конечную точку цикла (iЭта петля никогда не закончится.

Остановитесь и подумайте о том, что вы на самом деле пытаетесь сделать. Чтобы вычислить факториал, вам нужно умножить вместе все числа между ними. 1 и i.

Вам понадобится отдельная переменная для хранения результата, чтобы вы не перезаписывали его i Эта переменная изначально должна быть установлена в значение 1 перед началом цикла.


CPallini

5.

Рейтинг:
1

CPallini

Возможно, более "здравый" подход к этой функции

int factorial(int i)
{
    int x, fact;
    // 'i' contains the passed argument, no need to change it
    // 'fact' holds the result
    // 'x' is the looping variable
    for(fact = 1, x=2; x <= i; ++x)
    {
        fact *= x;
    }
    return fact;
}


Stefan_Lang

Я согласен, но сомневаюсь, что этот совет сильно поможет без объяснения того, почему это более разумно.

(кроме того, но это всего лишь ИМХО, было бы еще яснее, если бы вы объявили этот аргумент функции const - это сделало бы невозможным злоупотребление им как локальной переменной)

Рейтинг:
1

Stefan_Lang

Основываясь на понимании, предложенном в решении 1, Самым простым решением будет инвертирование вашего цикла for:

for (int x = i-1; x > 1; --x)
   i *= x;

Но, честно говоря, я бы не советовал использовать входные данные в качестве локальной, узловой переменной. Решение 3 гораздо лучше в этом отношении: оно не изменяет i и, следовательно, не сталкивается с проблемой, которая была у вас.

Как правило: не изменяйте входные данные функции, если это не то, что должна делать функция. Объявление дополнительной переменной требует всего лишь тривиального количества ввода текста, но это сэкономит вам массу времени, чтобы не искать какие-то непонятные ошибки, подобные этой.

Еще более общее правило: чем более подробно вы пишете свой код, тем труднее будет скрыть ошибки. Поэтому не уклоняйтесь от длинных имен или дополнительных строк кода, если это облегчает чтение и понимание вашего кода.