#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;
}
Анализируя его, вы обнаружите, что функция возвращает сумму элементов массива верхней половины (если количество элементов нечетное, то эта половина больше на единицу, чем нижняя половина).