Предположим, что у меня есть.

 char c[500]; 

У меня есть следующая функция, которую я написал для своего назначения: (По сути, это дерево, инфиксный порядок, если левый узел существует, запишите 0 (1 для правого) в буфер в позиции i, иначе напишите '\ 0' и распечатайте буфер).

void imprimer_codes (node *b, char *c, int i) {
  assert(c);
  if (!b) return;

  if (est_feuille(b)) {
    c[i] = '\0';
    printf("%s:%c\n",c,b->symbol);
  }

  if (b->fg) {
    c[i] = '0';
    imprimer_codes(b->fg,c,i+1);
  }

  if (b->fd) {
    c[i] = '1';
    imprimer_codes(b->fd,c,i+1);
  }
}

Поскольку я использую его рекурсивно. Я не понимаю, как функция может печатать несколько разных буферов, поскольку в буфере несколько \ 0.

Не копируется ли указатель на c [500] в стековую память? Возможно, это единственное объяснение, которое я могу найти.

0
NoobZik 3 Дек 2018 в 19:49

1 ответ

Лучший ответ

Поскольку я использую его рекурсивно. Я не понимаю, как функция может печатать несколько разных буферов, поскольку в буфере несколько \ 0.

Это довольно просто. В качестве примера рассмотрим дерево,

   *
 /   \
x    ...

То есть с листом слева и некоторым поддеревом справа.

i = 0, c = [] 

Ваш алгоритм сначала идет влево (все равно нужно идти вправо),

i = 1, c = [0]

Это лист, поэтому он добавляет ноль,

i = 1, c = [0, \0]

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

i = 0, c = [0, \0]

Помните, что i передается по значению, но c является массивом, а массивы передаются по ссылке. Итак, мы идем направо,

i = 1, c = [0, 1]

И нуль исчез.

Еще один пример, когда нуль не отменяется. Рассмотреть возможность,

    *
  /   \
 /     y
x   

Иди дважды налево,

i = 0, c = []
i = 1, c = [0]
i = 2, c = [0, 0]

Затем вы добавляете нуль и печатаете

i = 2, c = [0, 0, \0]    

Поскольку в корне есть только правая ветка, она вернется туда,

i = 0, c = [0, 0, \0]     

И тогда все идет правильно,

i = 1, c = [1, 0, \0]     

И это лист, поэтому мы добавим нуль и распечатаем его,

i = 1, c = [1, \0, \0]     

Думаю, этого должно быть достаточно, чтобы понять, что происходит.

В точке сразу после вставки \0 вы возвращаетесь к меньшему i и продолжаете оттуда строить новую строку. Так что никогда и никогда у вас не будет \0 в позиции перед вашим текущим i.

0
Jorge Adriano 3 Дек 2018 в 19:54