Простая программа на языке Си и понимание вывода

#c

Вопрос:

На следующей неделе у меня будет экзамен от Си. Мне придется ввести, каков вывод данных программ на языке Си. Мы также получаем некоторые примеры этих программ, чтобы знать, к чему готовиться. К сожалению, у меня сейчас не так много времени, чтобы глубоко погрузиться в C, поэтому я пытаюсь просто получить некоторые общие знания.

Итак, у меня есть данная программа:

 #include <stdio.h>
int A[] = {1,2,3,5,7,11,13,17,19};
#define MaxJ (sizeof A / sizeof A[0]-1)

int tot(int j)
{
    if (2*j <= MaxJ)
        return tot(2*j)   tot(2*j 1);
    else if (j<=MaxJ)
        return A[j];
    else return 0;
}
int main()
{
    printf("%d", tot(1));
    return 0;
}
 

Вопрос в том, что именно происходит в этом утверждении «если»? Я понимаю, что MaxJ равен 8 и почему, но вывод 60 меня смущает. Из того, что я подумал, мы передаем значение 1 в качестве аргумента tot (), затем умножаем это значение 1 на 2, пока не получим 16, что > MaxJ, поэтому мы переходим к другому, если и возвращаем[j], которое должно быть 19 для j = 8. Но это неверно.

Комментарии:

1. » затем умножаем это 1 на 2, пока не получим 16 «. Это подразумевает петлю. Но an if — это не петля. Так как же происходит «пока мы не доберемся» в вашем понимании? Это рекурсивная функция (т. Е. вызывает саму себя), и, по общему признанию, их поначалу может быть трудно понять. То, что вы описали, является только последним вызовом в одной из ветвей дерева вызовов. Этот результат необходимо передать обратно в дерево вызовов вплоть до первоначального вызова. Лучше всего написать это строчка за строчкой на листе бумаги. Вам нужно рекурсивно вычислить результат tot и выложить полное дерево вызовов.

2. Спасибо за Ваши усилия. Я выполнил вашу инструкцию и записал ее на листке бумаги, теперь я вижу, откуда взялись эти 60. Я прошелся по ветвям и увидел, что отдельные «возвраты» из ветвей составляют a[8]=19, 0, a[5]=11, a[6]=13, a[7]=17. Я все еще не понимаю, почему эти значения могут быть добавлены.

Ответ №1:

Если вы добавите некоторые отладочные printf модули, вы сможете увидеть, что происходит:

 int A[] = {1,2,3,5,7,11,13,17,19,20,21,22,23,24,25,26,27,28};
#define MaxJ (sizeof A / sizeof A[0]-1)

int tot(int j)
{
    if (2*j <= MaxJ)
    {
        printf(" >>>> j = %d 2*j = %dn", j, 2*j);
        return tot(2*j)   tot(2*j 1);
    }
    else 
    if (j<=MaxJ)
    {
        printf("j = %d A[j] = %dn", j, A[j]);
        return A[j];
    }
    else return 0;
}
int main()
{
    printf("MAXJ = %zun", MaxJ);
    printf("%d", tot(1));
    return 0;
}
 

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