Как инициализировать массив указателей в NULL? - PullRequest
1 голос
/ 20 апреля 2020

Я реализовывал Radix Sort, который требовал массив указателей, и чтобы избежать ошибки сегментации, я должен инициализировать его как NULL.

Когда я пытался: struct Node *Bucket[10] = NULL

Но это дает: error: invalid initializer

Итак, мой учитель предложил: struct Node *Bucket[10] = {0}

Итак, мой вопрос, в чем разница между {0} и NULL, и я также попытался:

struct Node *Bucket[10] ;

     for(int i=0 ; i<10 ; i++)
     {
             Bucket[i] = NULL ;
     }

Как {0} это то же самое для l oop

Редактировать 1:

Есть дополнительный вопрос, почему мы делаем Bucket [0] .. Bucket [9] как NULL и как это предотвращает ошибку сегментации.

void Radix_Sort(int *Arr)
{
    int max ;

    max = Max_element_in_array(Arr);

    struct Node *Bucket[10] = {0} ;

    for(int exp = 1 ; max / exp > 0 ; exp*=10)
    {
        int k=0 ;

        for(int i=begin ; i<end ; i++)
        {
            Append_a_linked_list(&Bucket[(Arr[i]/exp)%10],Arr[i]);
        }

        for(int j=0 ; j<10 ; j++)
        {
            while( Bucket[j] )
            {
                Arr[k++] = Delete_first_node(&Bucket[j]);
            }
        }
    }
}

Ответы [ 2 ]

5 голосов
/ 20 апреля 2020

Фигурные скобки { ... } используются для инициализации массива . Когда вы объявляете массив, вы можете инициализировать его элементы следующим синтаксисом:

int a[3] = {1, 2, 3};

, который устанавливает для трех членов соответственно a[0] = 1, a[1] = 2 и a[2] = 3.

Если в списке содержится меньше значений, чем в массиве, то все остальные элементы инициализируются нулями. По приведенной выше ссылке:

Все элементы массива, которые не инициализированы явно, инициализируются неявно так же, как и объекты, которые имеют c продолжительность хранения.

Ваш Массив указателей имеет 10 элементов, но в списке инициализатора есть только одно значение, поэтому все остальные устанавливаются в ноль (как и первый элемент, явно).

На самом деле вы используете NULL только в Сама проблема, как вы могли бы написать (более четко, ИМХО):

struct Node *Bucket[10] = {NULL, };

, поскольку макрос NULL обычно определяется следующим образом:

#define NULL ((void *)0)

Примечание: завершающий запятая, которую я указал в списке инициализаторов, otional , но (опять же, IMHO) проясняет (э), что вы знаете, , есть больше элементов в массиве, и что вы сознательно используете правило «неявной инициализации в ноль». Для обсуждения см. Здесь: История запятой в грамматиках языка программирования .

Не стесняйтесь просить дальнейших разъяснений и / или объяснений.

3 голосов
/ 20 апреля 2020

Согласно C Языку программирования По Брайану Кернигану и Деннису М. Ричу ie, Секция 4,9 Инициализация : "Есть невозможно указать повторение инициализатора или инициализировать элемент в середине массива, не указав также все предыдущие значения. " Эти авторы уполномочены определять, что разрешено в C.

. Таким образом, правильное решение выглядит следующим образом:

struct Node *Bucket[10] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};

Но ... по словам тех же авторов: " symboli c константа NULL часто используется вместо нуля, как мнемоника c, чтобы более четко указать, что это специальное значение для указателя. NULL определено в <stdio.h>. " (См. Раздел: 5.4 Адрес Арифмети c)

Итак, учитель прав, когда он предлагает инициализировать как:

struct Node *Bucket[10] = {0};

, потому что "если есть меньше инициализаторов для массива, чем указанный размер, остальные будут равны нулю для внешних переменных: stati c и automati c. " (См. Раздел: 4.9 Инициализация )

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...