Зависит от того, где написан код. Рассмотрим:
int i;
int data[5] = {0};
void func1(void)
{
data[0] = i;
}
void func2(void)
{
int i;
int data[5] = {0};
data[0] = i;
...
}
Значение, присвоенное data[0]
в func1()
, является полностью детерминированным; он должен быть нулевым (при условии, что никакие другие назначения не влияли на значения глобальных переменных i
и data
).
Напротив, значение, установленное в func2()
, является полностью неопределенным; Вы не можете достоверно указать, какое значение будет присвоено data[0]
, поскольку в функции не было надежно назначено значение i
. Вероятно, это будет значение, которое было в стеке от какого-то предыдущего вызова функции, но оно зависит как от компилятора, так и от программы и даже не «определено реализацией»; это чисто неопределенное поведение.
Вы также спрашиваете «Что это значит?»
if (!data[0]) { ... }
Оператор '!
' делает логическое инвертирование значения, к которому он применяется: он отображает ноль в единицу и отображает любое ненулевое значение в ноль. Общее условие оценивается как истинное, если выражение оценивается как ненулевое значение. Таким образом, если data[0]
равно 0, !data[0]
отображается на 1 и код в блоке выполняется; если data[0]
не равно 0, !data[0]
отображается на 0 и код в блоке не выполняется.
Это широко используемая идиома, потому что она более краткая, чем альтернатива:
if (data[0] == 0) { ... }