Что {0} означает при инициализации объекта?

Другое событие NullPointerException возникает, когда объявляется массив объектов, а затем сразу же пытается разыменовать его внутри.

String[] phrases = new String[10];
String keyPhrase = "Bird";
for(String phrase : phrases) {
    System.out.println(phrase.equals(keyPhrase));
}

Этот конкретный NPE можно избежать, если порядок сравнения отменяется ; а именно, использовать .equals для гарантированного непустого объекта.

Все элементы внутри массива инициализируются их общим начальным значением ; для любого типа массива объектов, это означает, что все элементы null.

Вы должны инициализировать элементы в массиве перед доступом или разыменованием их.

String[] phrases = new String[] {"The bird", "A bird", "My bird", "Bird"};
String keyPhrase = "Bird";
for(String phrase : phrases) {
    System.out.println(phrase.equals(keyPhrase));
}

250
задан Mahmoud Al-Qudsi 8 July 2017 в 07:54
поделиться

6 ответов

Что происходит, здесь назван агрегат инициализация. Вот является (сокращенное) определение агрегата от раздела 8.5.1 из спецификации ISO:

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

Теперь, с помощью {0} для инициализации агрегата как это в основном прием к 0 вся вещь. Это вызвано тем, что при использовании совокупной инициализации Вы не должны определять всех участников , и спецификация требует, чтобы все неуказанные участники были инициализированным значением по умолчанию, что значит набор для 0 для простых типов.

Вот соответствующая кавычка от спецификации:

, Если в агрегате существует меньше инициализаторов в списке, чем, существуют участники, то каждый участник, не явно инициализированный, должен быть инициализирован значением по умолчанию. Пример:

struct S { int a; char* b; int c; };
S ss = { 1, "asdf" };

инициализирует ss.a с 1, ss.b с "asdf", и ss.c со значением выражения формы int(), то есть, 0.

можно найти полную спецификацию по этой теме здесь

298
ответ дан Don Neufeld 23 November 2019 в 02:56
поделиться

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

struct foo
{
    char c;
    int  i;
};

foo a = {0};

Не то же как:

foo a;
memset(&a,0,sizeof(a));

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

89
ответ дан Harold Ekstrom 23 November 2019 в 02:56
поделиться

Обратите внимание, что также работает пустой совокупный инициализатор:

SHELLEXECUTEINFO sexi = {};
char mytext[100] = {};
20
ответ дан dalle 23 November 2019 в 02:56
поделиться

Я также использую его для инициализации строк, например,

char mytext[100] = {0};
7
ответ дан Adam Pierce 23 November 2019 в 02:56
поделиться

Это было некоторое время, так как я работал в c/c ++, но IIRC, тот же ярлык может использоваться для массивов также.

3
ответ дан µBio 23 November 2019 в 02:56
поделиться

In answer to why ShellExecuteEx() is crashing: your SHELLEXECUTEINFO "sexi" struct has many members and you're only initializing some of them.

For example, the member sexi.lpDirectory could be pointing anywhere, but ShellExecuteEx() will still try to use it, hence you'll get a memory access violation.

When you include the line:

SHELLEXECUTEINFO sexi = {0};

before the rest of your structure setup, you're telling the compiler to zero out all structure members before you initialize the specific ones you're interested in. ShellExecuteEx() knows that if sexi.lpDirectory is zero, it should ignore it.

11
ответ дан Ziezi 23 November 2019 в 02:56
поделиться