2013-11-08 4 views
1

С ISO/IEC 9899: 1999 -> 6.7.8 Инициализация § 10Является ли каждый элемент статического массива инициализированным?

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

- если у него есть указатель, он инициализируется нулевым указателем;

- если у него арифметический тип, он инициализируется (положительным или без знака) нулем;

- если это совокупность, каждый член инициализируется (рекурсивно) в соответствии с этими правилами;

- если это объединение, первый именованный элемент инициализируется (рекурсивно) в соответствии с этими правилами .

ли я получить это право, что представить себе этот код:

int main() 
{ 
    static char *szArray[4]; 
    return 0; 
} 

гарантируется, что каждый член szArray[] инициализируется NULL? Или как я могу понять «рекурсивно» в этом контексте?

+0

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

+0

@hyde Ну, я не разрабатываю программное обеспечение для клиентов. Я разрабатываю сервер для себя, который компилируется и запускается на archix FreeBSD x86. Так что, наверное, я не буду бежать в беде, не так ли? – dhein

+0

Если вы принимаете значения указателя, это NULL, что гарантируется стандартом C. Я просто имел в виду, вы также можете визуализировать ситуацию как область с нулевым объемом памяти на практике (на любом мобильном устройстве или мобильном устройстве). – hyde

ответ

4

Да.

szArray представляет собой массив из 4 элементов, каждый из которых является указателем char*. Каждый из этих 4 элементов инициализируется в NULL.

Что «рекурсивно» здесь означает, что, так как типы данных могут быть сколь угодно сложными (массивы внутри структур внутри союзов внутри массивов и т.д.), каждый член из совокупности (массива или структуры) инициализируется следуя той же правила.

  • szArray - это совокупность, поэтому «каждый элемент инициализируется (рекурсивно) в соответствии с этими правилами».
    • szArray[0] через szArray[3] все имеют указательный тип, поэтому каждый из них «инициализируется нулевым указателем».

Это (вероятно) не предполагает какую-либо время выполнения рекурсии. В большинстве систем целое число 0, с плавающей запятой 0.0 и нулевые указатели представляются как все-бит-ноль, поэтому статический агрегированный объект может , вероятно, быть правильно инициализирован, просто установив его на все биты-ноль. Это определение , что является рекурсивным; инициализация совокупного объекта определяется в терминах инициализации его элементов/членов и т. д. рекурсивно, пока вы не перейдете к отдельным скалярам.

+0

Итак, если существует структура из 3 указателей типа 'struct {int * i; int * j; int * k;} type;' then для массива типа 'type [3];' each 'i',' j' и 'k' будет NULL инициализирован? – dhein

+2

@ Заиби: Точно. Объектами арифметики или типа указателя являются * скаляры *. Все типы объектов являются либо самими скалярами, либо составлены (прямо или косвенно) скаляров (я игнорирую 'void', так как вы не можете иметь объект типа' void' в любом случае). Для любого статического объекта без инициализатора каждый из скаляров, которые его составляют, инициализируется нулем или нулевым указателем. –

1

Каждый элемент szArray действительно инициализирован NULL, один раз, перед его использованием. В main этот «один раз» не имеет значения, но в других функциях, которые можно вызвать много раз, важно.Это особенно важно для кода, защищенного потоком, и кода повторного входа, поскольку для всех вызовов доступно только одно значение.

+0

Именно поэтому я сейчас работаю с этим, так как мне приходится писать код, который выделяет только первую память. И должен работать поточно. Но это не имеет значения. так спасибо :), но я должен принять ответ Кейта, поскольку он более явно. – dhein

1

Да, в этом случае вы получите массив из четырех значений NULL.

«Рекурсивно» в спецификации не применяется к указателям. Это относится к структурам. Так, например.

#include <stdio.h> 

struct Bar { 
    int yada; 
}; 

struct Foo { 
    struct Bar bar; 
    const char* baz; 
}; 

static struct Foo foo; 
static struct Foo* foo_ptr; 

int main() 
{ 

    printf("foo.bar.yada = %d\n", foo.bar.yada); 
    printf("foo_ptr = %p\n", foo_ptr); 

    return 0; 
} 

Запуск выше дает

foo.bar.yada = 0 
foo_ptr = (nil) 

Правило инициализации было применено рекурсивно к Foo, а затем в баре. Указатель просто инициализируется до нуля.

+0

Вы уверены, что это то, что упоминается рекурсивно? Поскольку ваш пример не является чем-то, я бы назвал рекурсию каким-либо образом. – dhein

+0

В C99 нет классов. Есть, однако, массивы, и в вопросе конкретно упоминается массив, поэтому вы можете его осветить. –

+0

@PascalCuoq спасибо, что поймал мою ошибку при обращении к C++, когда вопрос задавал вопрос о простой C. Я удалил ссылку на класс из моего ответа. Я попытаюсь вернуться позже и задать вопрос о массивах. –

Смежные вопросы