У C є (дурне) правило, яке говорить, що будь-яка звичайна змінна може бути ініціалізована списком ініціалізатора, укладеним у фігурні дужки, так само, ніби це масив.
Наприклад, ви можете писати int x = {0};
, що повністю еквівалентно int x = 0;
.
Отже, коли ви пишете, int *nums = {5, 2, 1, 4};
ви фактично надаєте список ініціалізатора одній змінній покажчика. Однак це лише одна змінна, тому їй буде призначено лише перше значення 5, решта списку ігнорується (насправді я не думаю, що код із надлишком ініціалізаторів повинен навіть компілюватись із суворим компілятором) - це не записуватись на пам’ять взагалі. Код еквівалентний int *nums = 5;
. Що означає, nums
слід вказувати на адресу 5
.
На цей момент ви вже мали отримати два попередження / помилки компілятора:
- Присвоєння цілого числа покажчику без приведення.
- Надлишки елементів у списку ініціалізатора.
І тоді, звичайно, код вийде з ладу і згорить, оскільки 5
, швидше за все, це не дійсна адреса, з якої вам дозволено відмінюватися nums[0]
.
Як допоміжне зауваження, слід вказати printf
адреси на %p
специфікатор, інакше ви використовуєте невизначену поведінку.
Я не зовсім впевнений, що ви намагаєтесь зробити тут, але якщо ви хочете встановити вказівник, який би вказував на масив, вам слід зробити:
int nums[] = {5, 2, 1, 4};
int* ptr = nums;
int* ptr = (int[]){5, 2, 1, 4};
Або якщо ви хочете створити масив покажчиків:
int* ptr[] = { };
РЕДАГУВАТИ
Після деяких досліджень я можу сказати, що «список ініціалізаторів надлишкових елементів» дійсно не є дійсним C - це розширення GCC .
Стандарт 6.7.9 Ініціалізація говорить (наголос на моєму):
2 Жоден ініціалізатор не повинен намагатися надати значення для об'єкта, який не міститься в сутності, що ініціалізується.
/ - /
11 Ініціатором для скаляра повинен бути єдиний вираз, необов’язково укладений у фігурні дужки. Початкове значення об'єкта - значення виразу (після перетворення); застосовуються ті самі обмеження типу і перетворення, що і для простого присвоєння, приймаючи тип скаляра як некваліфіковану версію заявленого типу.
"Скалярний тип" - це стандартний термін, що стосується одиничних змінних, які не мають масиву, структури або об'єднання (вони називаються "агрегатним типом").
Отже, простою англійською мовою стандарт говорить: "коли ви ініціалізуєте змінну, сміливо кидайте кілька зайвих дужок навколо виразу ініціалізатора, просто тому, що можете".