2015-04-11 2 views
2

Я новичок в программировании на C и я нашел что-то я не понимаю:Странные значения при инициализации массива

При инициализации массива без заданных значений, я думал, что все элементы будут равны нулю. Я написал эти несколько строк кода ...

int main()      
{  
    int obj[10][4]; 

    for (int a = 0; a < 10; a++) 
    { 
     print("%d\t%d\t%d\t%d\n", obj[a][0], obj[a][1], obj[a][2], obj[a][3]); 
    }    
} 

... и был очень смущен своей продукции:

0  0  0  0 
0  0  0  0 
0  0  0  0 
0  0  0  0 
0  0  0  0 
0  0  0  0 
0  0  0  0 
0  0  0  7661 
7960 2697 2260 7960 
1551630361  -2130960380  146780176  -2130960380 

Я не понимаю, почему некоторые значения равны нулю, а некоторые из них не. Я был еще более смущен, что эти цифры меняются, когда я добавляю больше кода. Например, я изменил предыдущий пример и добавили еще один print() ...

int main()      
{  
    int obj[10][4]; 

    print("start\tstop\tcenter\tdist\n\n"); 

    for (int a = 0; a < 10; a++) 
    { 
     print("%d\t%d\t%d\t%d\n", obj[a][0], obj[a][1], obj[a][2], obj[a][3]); 
    }    
} 

... получаю это:

start stop center dist 

0  0  0  0 
0  0  0  0 
0  0  0  0 
0  0  0  0 
0  0  0  0 
0  0  0  0 
0  0  0  0 
0  0  0  7673 
7972 2709 2272 7972 
1551630361  -2130960380  146780176  -2130960380 

Используя больший массив, эти цифры находятся не только в его конце. Первые несколько значений всегда равны нулю, но затем происходит «что-то».

Я нашел решение here at SO, используя memset(), что работает для меня, но ... что здесь происходит?

Может кто-нибудь объяснить это, используя слова, которые C-новичок поймет?

+0

Ну, вы не инициализировали, поэтому получаете неинициализированные значения. В основном нули, но никогда не гарантируется. – stefan

+0

Совет для дальнейшего развития: если вы получаете _unexpected_ поведение с действительно странными значениями, попробуйте выполнить команду 'valgrind'. Это может дать вам подсказки, где ошибка (неинициализированные переменные довольно хорошо обнаруживаются valgrind). – stefan

+0

@stefan: Спасибо за эту информацию, но сейчас это слишком много. Я посмотрел «valgrind» и добавил закладки в некоторые сайты, которые я мог бы понять, после использования C немного дольше ;-) – xph

ответ

2

У вас есть объявление переменной, но нет инициализации.

Если вы хотите, чтобы ваш массив будет нулевой инициализируется просто поставить это:

int obj[10][4] = {0}; 
+0

Спасибо! Теперь я знаю ошибку, которую я сделал - только если определены * некоторые * значения, остальные будут равны нулю. Сделай это! – xph

1

Начальные значения ничего не определены. Ваш код просто определяет массив - он никогда не присваивает никакого значения тому, что в нем.

+0

Да, но примеры, которые я встретил, показывают, что «нет значения» означает «ноль, затем». Получил ли я это неправильно и «нет значения» просто означает «что угодно» ..? – xph

+0

@xph Да, именно там вы ошибаетесь. Неинициализация означает значения мусора. – stefan

+0

@stefan: Получил! :-) – xph

4

Проще говоря, вы не можете предположить, что массив инициализирован до 0, если вы явно не сделали инициализацию самостоятельно. Стандарт C не гарантирует ничего о содержимом массива, просто у вас будет выделенная память.
Отличную ссылку на инициализацию и массивы в общем случае можно найти здесь: http://www.tutorialspoint.com/cprogramming/c_multi_dimensional_arrays.htm

+0

... так что я понял, что ошибаюсь. Спасибо за объяснение и ссылку! – xph

0

стек содержит мусор, пока программа не ставит конкретные значения в переменные, определенные в стеке. Код запуска не инициализирует содержимое стека.

Примечание: переменные глобального пространства/файла глобального пространства инициализируются кодом запуска. где не указан какой-либо конкретный инициализатор, тогда память устанавливается на 0x00.

1

Тип хранилища int obj[10][4] is auto и хранится на стеке. auto переменные не получают инициализированные значения, т. Е. Имеют значения мусора. Если вы хотите, чтобы массив инициализировался нулями, сделайте его глобальным, то есть объявите массив вне функции main().

0

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

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

0

не эксперт, но гипотеза из опыта:

Если инициализировать массив как static int myArray[1000], то C выделяет новую память, заполненные нулями 1000 для продолжительности программы. Инициализация с помощью int myArray[1000] просто ограничивает 1000 регистров, некоторые из которых могут содержать старые значения из предыдущего использования регистра.

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