Member 13248267 Ответов: 1

Почему мой код терпит крах?


#include <stdio.h>
#include <stdlib.h>

void jum(int *p, int m, int n)
{
    int i;
    if(m==(n-1))
        return;
    if(n%2==0)
    {
        for(i=m;i<n/2;i++)
            (*(p+i))--;
        for(i=n/2;i<n;i++)
            (*(p+i))++;
    }
    else
    {
        for(i=m;i<n/2;i++)
            (*(p+i))--;
        for(i=(n/2)+1;i<n;i++)
            (*(p+i))++;
    }
    jum(p,0,n/2);
    jum(p,n/2,n);
    return;
}

int main()
{
    int n,i;
    printf("n = "); scanf("%d",&n);
    int v[n];
    int *p;
    p=&v[0];
    for(i=0;i<n;i++)
    {
        printf("v[%d] = ",i+1); scanf("%d",&v[i]);
    }
    jum(p,0,n);
    for(i=0;i<n;i++)
        printf("%d ",*(p+i));
    return 0;
}


Нет никакой ошибки/предупреждения, но после того, как я даю свои векторные значения, он падает. У меня есть вектор с n элементами, а затем я хотел разделить вектор пополам, левая сторона будет иметь свои элементы, уменьшенные на 1, а правая сторона будет иметь свои элементы, добавленные на 1. Если n неравномерно, то элемент в середине останется тем же самым. После того как вектор будет разделен пополам, каждая половина будет разделена снова, пока не останется 1 элемент.

Например:

n=5;
v={1 , 2 , 3 , 4 , 5};
Окончательная печать: 0 1 3 5 6

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

Я действительно не знаю, что еще попробовать. Я продолжал изменять код, пока не достиг этой стадии, которая, с моей точки зрения, должна была сработать. Я попробовал более простой код с той же идеей, и он сработал, но не совсем уверен, почему он здесь выходит из строя. Вероятно, потому, что я снова вызываю функцию в функции.

1 Ответов

Рейтинг:
5

OriginalGriff

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

И вот вы вступаете во вторую стадию развития (на самом деле это четвертая или пятая
но к более ранним этапам вы перейдете позже): тестирование и отладка.

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

Input   Expected output    Actual output
  1            2                 1
  2            4                 4
  3            6                 9
  4            8                16
Тогда совершенно очевидно, что проблема заключается в бите, который удваивает его-он не прибавляет себя к себе или умножает его на 2, он умножает его на себя и возвращает квадрат входного сигнала.
Таким образом, вы можете посмотреть на код, и очевидно, что он где-то здесь:
private int Double(int value)
   {
   return value * value;
   }

Как только у вас появится идея, что может пойти не так, начните использовать отладчик, чтобы выяснить почему. Поставить точку останова на строке:
p=&v[0];

и запустите свое приложение. Подумайте о том, что должна делать каждая строка кода перед ее выполнением, и сравните это с тем, что она на самом деле делала, когда вы использовали кнопку "шаг вперед" для выполнения каждой строки по очереди. Он сделал то, что вы ожидали? Если да, то переходите к следующей строке.
Если нет, то почему? Чем это отличается?

Это навык, и его стоит развивать, поскольку он помогает вам как в реальном мире, так и в развитии. И, как и все навыки, он совершенствуется только при использовании!

Да, я, наверное, мог бы сказать вам, в чем "проблема" - но сделать это самому несложно, и при этом вы узнаете что-то действительно стоящее!


Member 13248267

jum(p,(n/2)+1,n);


Проблема заключалась во втором вызове функции. Я новичок и, должен сказать, никогда не пользовался отладчиком и толком не знаю, как он работает. Хотя я видел, что проблема была в вызове функции внутри функции. Чтобы проверить свой код, я обычно использую «//» или «/ * * /» и запускаю его, чтобы проверить, работает ли он. Моя ошибка заключалась в том, что внутри функции "jum" я проверял только первый вызов, он работал и не проверял второй. Я до сих пор не совсем уверен, что вызвало сбой кода. В чем разница между (n / 2) +1 и n / 2 (я должен сказать, что (n / 2) +1 показывает ответ, который я хотел))? И не могли бы вы сказать мне, что я сделал не так, поскольку я все еще учусь и все еще не могу найти «проблему».

OriginalGriff

Отладчик не является сложным - или, по крайней мере, не на этом уровне - все, что вам нужно сделать, это использовать его, чтобы шагать через ваш код строка за строкой, чтобы узнать, что происходит, глядя на переменные и данные, как вы это делаете. Обычно это очень легко сделать - я не могу сказать вам, что именно делать, так как понятия не имею, какую систему разработки вы используете, но если вы загуглите название своей системы разработки и "отладчик", вы получите много информации: например, "отладчик Visual Studio" дает вам полмиллиона просмотров, и первые три расскажут вам больше, чем вы хотите знать!
Попробуйте: стоит развивать этот навык на небольших программах, подобных этой, вместо того, чтобы пытаться начать с бегемота в 100 000 строк.