Подтвердить что ты не робот

Начальное значение массива int в C

При объявлении массива в C, как это:

int array[10];

Каково начальное значение целых чисел? Я получаю разные результаты с разными компиляторами, и я хочу знать, имеет ли он какое-то отношение к компилятору или ОС.

4b9b3361

Ответ 1

Если массив объявлен в функции, то значение undefined. int x[10]; в функции означает: взять собственность на 10-ти размерную область memroy без инициализации. Если массив объявлен как глобальный или как static в функции, то все элементы инициализируются до нуля, если они уже не инициализированы.

Ответ 2

Как установлено стандартом, все глобальные и функциональные статические переменные автоматически инициализируются до 0. Автоматические переменные не инициализируются.

int a[10];  // global - all elements are initialised to 0

void foo(void) {
    int b[10];    // automatic storage - contain junk
    static int c[10]; // static - initialised to 0
}

Однако рекомендуется всегда вручную инициализировать функциональную переменную независимо от ее класса хранения. Чтобы установить все элементы массива в 0, вам просто нужно назначить первый элемент массива 0 - пропущенные элементы будут автоматически установлены на 0:

int b[10] = {0};

Ответ 3

Почему локаторы функций (auto класс хранения) не инициализируются, когда все остальное?

C близок к оборудованию; что его наибольшая сила и самая большая опасность. Причина auto объектов класса хранения имеет случайные начальные значения, потому что они выделены в стеке, и было принято конструктивное решение не автоматически очищать их (отчасти потому, что их нужно было очистить при каждом вызове функции).

С другой стороны, объекты не auto должны быть удалены только один раз. Кроме того, ОС в любом случае должна очистить выделенные страницы по соображениям безопасности. Таким образом, конструктивное решение заключалось в том, чтобы указать нулевую инициализацию. Почему безопасность не является проблемой для стека? На самом деле сначала очищается. Убой, который вы видите, - это более ранние экземпляры ваших собственных кадров программных вызовов и код библиотеки, который они вызывали.

Конечный результат - быстрый, эффективный с точки зрения памяти код. Все преимущества сборки без какой-либо боли. До того, как dmr изобрел C, "HLL", подобно основным и целым ядрам ОС, действительно был реализован как гигантские ассемблерные программы. (С некоторыми исключениями в таких местах, как IBM.)

Ответ 4

Согласно стандарту C, 6.7.8 (примечание 10):

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

Так что это зависит от компилятора. С MSVC отладочные сборки будут инициализировать автоматические переменные с помощью 0xcc, тогда как не-отладочные сборки не будут инициализировать эти переменные вообще.

Ответ 5

Объявление переменной C просто указывает компилятору выделить и назвать область памяти для вас. Для автоматических переменных, также называемых переменными стека, значения в этой памяти не изменяются с того, что было раньше. Глобальные и статические переменные равны нулю при запуске программы.

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

Чтобы попросить компилятор установить для вас массив нуль, вы можете записать его как:

int array[10] = {0};

Еще лучше установить массив со значениями, которые он должен иметь. Это более эффективно и позволяет дважды записывать в массив.

Ответ 6

В большинстве последних компиляторов (например, gcc/vС++) частично инициализированные локальные элементы массива/структуры по умолчанию инициализируются нулем (int), NULL (char/char string), 0.000000 (float/double).

Помимо локальных данных массива/структуры, как указано выше, статические (глобальные/локальные) и глобальные элементы пространства также сохраняют одно и то же свойство.

int a[5] = {0,1,2};
printf("%d %d %d\n",*a, *(a+2), *(a+4));

struct s1
{
int i1;
int i2;
int i3;
char c;
char str[5];
};

struct s1 s11 = {1};
    printf("%d %d %d %c %s\n",s11.i1,s11.i2, s11.i3, s11.c, s11.str);
    if(!s11.c)
        printf("s11.c is null\n");
    if(!*(s11.str))
        printf("s11.str is null\n");

В gcc/vС++ вывод должен быть:

0 2 0 1 0 0 0,000000 s11.c имеет значение null s11.str имеет значение null

Ответ 7

Текст из http://www.cplusplus.com/doc/tutorial/arrays/

РЕЗЮМЕ:

Инициализация массивов. При объявлении регулярный массив локальной области (в пределах функция, например), если мы не указать иначе, его элементы будут не инициализируется никаким значением по по умолчанию, поэтому их содержимое будет неопределенные до тех пор, пока мы не сохраним некоторую ценность в них. Элементы глобального и статические массивы, с другой стороны, являются автоматически инициализируются значения по умолчанию, которые для всех фундаментальные типы, это означает, что они заполненный нулями.

В обоих случаях локальный и глобальный, когда мы объявляем массив, мы имеем возможность назначать начальные значения каждому из его элементов вставляя значения в фигурные скобки {}. Например:

int billy [5] = { 16, 2, 77, 40, 12071 };