Как прочитать это объявление / инициализация массива C? - PullRequest
3 голосов
/ 07 августа 2010
char *names[] = {
        [3] = "foo", 
        [1] = "bar", 
        [0] = "man"};

int i;
for (i=0; i<sizeof(names)/sizeof(char); i++)
{
    puts(names[i]);
}

Какова функция скобок в приведенной выше декларации? Кроме того, почему результирующий цикл повторяется 3 раза вместо 4 и выдает такой вывод:

человек

бар

Ответы [ 3 ]

4 голосов
/ 07 августа 2010

Следующее определение показывает, как можно использовать назначенные инициализаторы для пропуска элементов массива, которые вы не хотите инициализировать явно:

static int number[3] = { [0] = 5, [2] = 7 };

Номер массива содержит следующие значения: число [0] равно 5; число [1] неявно инициализируется до 0; число [2] равно 7.

Хит ниже, описывает эффект вашего цикла for, поэтому я не буду повторяться.

3 голосов
/ 07 августа 2010

Числа в скобках являются индексами инициализаторов. Это функция C99.

Учитывая, что ваш пример кода использует этот недостаток, вы получаете вывод, что «foo» хранится в names[3], а NULL хранится в names[2]. Ваша программа вылетает при попытке puts(names[2]), что совпадает с puts(NULL).

В противном случае ваш цикл будет повторяться до 16 или 32 итераций - вы делите на sizeof(char) размер элемента массива и хотите использовать sizeof(char *).

Лучше использовать этот макрос:

#define DIMENSION_OF (a) (sizeof(a)/sizeof(a[0]))

Я предлагаю никогда не использовать какие-либо специфичные для C99 функции, такие как эти «назначенные инициализаторы».

Существует причина, по которой большинство ответов, полученных вами на этот вопрос, были сбиты с толку из-за того, что ваш цикл выводит только две строки, а не четыре. Причина в том, что C99 не получил широкого признания других программистов.

Есть несколько причин, по которым большинство программистов не знакомы с более характерными особенностями C99. Часто упоминаемая причина заключается в том, что C99 более несовместим с C ++, чем ANSI C, и затрудняет возможность будущего преобразования в C ++. Моя личная жалоба с C99 также делает излишние расширения ANSI C. Примером лишнего дополнения является пример из C99, который вы предоставили. Не используйте «обозначенные единицы». Обратитесь к Американскому национальному институту стандартов С. Стандарт. Не ссылаться на документ Международной организации по стандартизации C99.

Большинство функций, которые «приятно иметь» в C99, уже были доступны как расширения во всех основных компиляторах. Объявление переменной в выражении for-init-example является примером не-ANSI-C-стандартной функции, которая широко поддерживается. Встроенный тип complex является примером не-ANSI-C-стандартной функции, которая широко не поддерживается.

2 голосов
/ 07 августа 2010

Он объявляет имена как массив (размер которого определяется компилятором) указателей на char, с инициализацией, которая также определяет размер массива; инициализация «решает» явно индекс конкретного указателя; например man с индексом 0, foo с индексом 3 ... Окончательный размер задается большим индексом, и все значения с индексами, не заданными явно, устанавливаются в ноль.

Это должно быть sizeof(char *), как уже было сказано. Цикл печатает содержимое; если количество элементов в массиве равно 3, индекс должен быть от 0 до 2 (2 <3, но 3 <3 - ложь), поскольку база индекса в C равна 0. </p>

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