2014-10-17 5 views
-3

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

#include <stdio.h> 

int main() 
{ 
    int arr[5]={0}; 
    int arr2[5]={0}; 
    printf("%d\n",arr[5]); //here output: 2130567168 
    printf("%d\n",arr2[5]); //here output: 0 
    return 0; 
} 

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

+6

Вы понимаете, что получаете доступ к своим массивам за пределы? вы выделили только пространство для 5-ти томов для обоих, но вы пытаетесь получить доступ к шестому – UnholySheep

+0

возможных дубликатов [Насколько опасно это доступ к массиву за пределами границ?] (http://stackoverflow.com/questions/15646973/how -dangerous-is-it-to-access-a-array-out-of-bounds) – Deduplicator

ответ

2

Вы получаете данные, находящиеся за пределами заявленного диапазона. Диапазон индексов вашего массива, объявленный как arr[5], идет от 0 ... 4, но вы хотите получить доступ к arr [5], который не определяется и не выделяется. Таким образом, вы получаете случайные ответы в зависимости от значения ячейки памяти, к которой вы хотите получить доступ, в этом случае 0 и другого номера.

+0

thanx, работающий с fortran90, который еще не используется для синтаксиса. почему второй вернулся 0? – yank1

+0

Потому что вам повезло? Запустите программу несколько раз и посмотрите на выход. –

+0

Я сделал, и это все равно одно и то же ...вот что меня смутило – yank1

3

И printf s производят неопределенное поведение, так как они обращаются к элементам за концом соответствующих им массивов. Допустимый диапазон для индексов C-массивов равен нулю от length-1, поэтому для обоих массивов в вашей программе будет 0..4 включительно.

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

+0

носовые демоны более интересны, и они не являются строго где-то между выводом мусора и сбоем. – Deduplicator

+2

@Deduplicator [Обязательный xkcd] (http://xkcd.com/292/) :-) – dasblinkenlight

0

Поведение этого кода в C описано в разделе 6.7.8.21 спецификации C (Online draft for c specs): для элементов, которые не имеют заданного значения, компилятор инициализирует указатели на NULL и арифметические типы до нуля (и рекурсивно применяет это к агрегатам).

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

2

В будущем, пожалуйста, включите предупреждения в своем компиляторе. Например, для GCC это будет -Wall.

main.cpp:7:29: warning: array subscript is above array bounds [-Warray-bounds] 
     printf("%d\n",arr[5]); //here output: 2130567168 
          ^
main.cpp:8:30: warning: array subscript is above array bounds [-Warray-bounds] 
     printf("%d\n",arr2[5]); //here output: 0 

Обратите внимание, что стандарт C говорит, что это не определено поведение:

§J.2

1 Поведение не определено в следующих случаях:

- индекс массива находится вне допустимого диапазона, даже если объект, по-видимому, , доступный с данным индексом (как в выражении lvalue a [1] [7], учитывая объявление int a [4] [ 5]) (6.5.6).

Получите вашу обычную лекцию о undefined behavior.

+0

Почему компиляция компилятора без -Wall? –

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