С помощью скобочных обозначений все неопределенные значения инициализируются равными 0. Так вот в чем разница.
С int ar[5]={1,3,5,7,9}
вы получаете массив, подобный этому (выложенный в памяти):
ar[5] = { 1, 3, 5, 7, 9 }
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
value | 1 | 3 | 5 | 7 | 9 | ??? | ??? | ??? | ??? | ??? |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
index | 0 | 1 | 2 | 3 | 4 | (5) | (6) | (7) | (8) | (9) |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
где (5)
означает, что ar[5]
может получить к нему доступ, но на самом деле он вне границы.
Поскольку вы не знаете, что может быть в ???
блоках, *p
является неопределенным(но обычно не ноль), и цикл продолжается, когда он видит ноль в памяти.Это может быть опасно !
С int ar[6]={1,3,5,7,9}
вы получите массив, подобный следующему:
ar[6] = { 1, 3, 5, 7, 9 }
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
value | 1 | 3 | 5 | 7 | 9 | 0 | ??? | ??? | ??? | ??? |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
index | 0 | 1 | 2 | 3 | 4 | 5 | (6) | (7) | (8) | (9) |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
Поэтому, когда p
указывает на ar + 5
, *p
оценивается как ложное и завершает цикл.