Чи покажчик, що вказує на 0x0000, такий же, як вказівник встановлений на NULL? Якщо значення NULL визначено мовою C, то в яке місце воно фізично перекладається? Це те саме, що і 0x0000. Де я можу знайти більш детальну інформацію про ці поняття?
Чи покажчик, що вказує на 0x0000, такий же, як вказівник встановлений на NULL? Якщо значення NULL визначено мовою C, то в яке місце воно фізично перекладається? Це те саме, що і 0x0000. Де я можу знайти більш детальну інформацію про ці поняття?
Відповіді:
Справа, на яку більшість відповідей тут не звертається, принаймні не явно, полягає в тому, що нульовий покажчик - це значення, яке існує під час виконання, а константа нульового покажчика - синтаксична конструкція, що існує у вихідному коді С.
Константний покажчик NULL , так як відповідь Карлсона правильно стверджує, або вираз постійного цілого числа зі значенням 0 (простим 0
є найбільш поширеним прикладом), або такого виразу приведення до void*
(наприклад (void*)0
).
NULL
це макрос, визначений у <stddef.h>
кількох інших стандартних заголовках, який розширюється до визначеної нульовою константою покажчика . Розширення, як правило, 0
або ((void*)0)
( або зовнішні дужки потрібні для задоволення інших мовних правил).
Таким чином, буквальний 0
при використанні в контексті, який вимагає вираження типу вказівника, завжди оцінює значення a null pointer
, тобто унікальне значення вказівника, яке вказує на жоден об'єкт. Це не означає нічого про представлення нульового покажчика . Нульові покажчики дуже часто представляються як всі біти-нулі, але вони можуть бути представлені як будь-що. Але навіть якщо нульовий покажчик представлений як 0xDEADBEEF
, 0
або (void*)0
все ще є константою нульового вказівника .
Ця відповідь на питання про stackoverflow охоплює це добре.
Це, серед іншого, означає, що memset()
або calloc()
, що може встановити область пам'яті на всі біти-нулі, не обов'язково встановлювати жодні покажчики в цьому регіоні на нульові покажчики. Вони, ймовірно, роблять це для більшості реалізацій, але мова не гарантує цього.
Я не знаю, чому це питання не вважається дублікатом цього питання , або наскільки це тут актуально.
NULL
або будь-яка константа нульового вказівника об'єкту вказівника встановлює значення цього об'єкта нульовому покажчику . На машинному рівні це може вказувати на якийсь дійсний шматок пам'яті. Перенаправлення нульового покажчика має невизначене поведінку; доступ до шматка пам'яті за адресою 0x0000000
- правильна поведінка, як і буквально все інше. Ця адреса відрізняється від будь-якої іншої адреси тим, що (a) порівнюється з рівним NULL
та (b) порівнюється нерівним з будь-яким вказівником на об'єкт C. Нульовий покажчик - це довільне значення вказівника, яке використовується для вказівки, що воно не вказує ні на що.
Кожна платформа, яка там є, може вільно визначити NULL так, як їй заманеться.
Відповідно до стандарту C, якщо ви призначите нуль покажчику, він буде перетворений на значення NULL (для цієї платформи.) Однак якщо ви візьмете покажчик NULL і киньте його до int, немає гарантій, що ви отримаєте нуль на кожній платформі там. Справа в тому, що на більшості платформ він буде нульовим.
Інформація про те , що матеріал , який Ви можете знайти в специфікації мови C . Одне джерело, на яке я не можу покластися, це: http://www.winapi.co.kr/pds/doc/ISO-C-FDIS.1999-04.pdf
NULL pointer constant
. Наскільки я знаю, там немає компіляторів, які б це робили.
NULL
макросу, який повинен розширюватися на 0
C ++ і або 0
або (void *)0
в C, тому що це справжня "нульова константа покажчика".
Він визначений мовою С, оскільки немає жодної незмінної адреси машини, до якої він прирівнюється. Якби це було, нам не потрібна була б абстракція від нього! Навіть незважаючи на те, що на більшості платформ NULL з часом може бути реалізований як 0 певного типу чи іншого, просто неправильно вважати, що це так універсально, якщо ви взагалі дбаєте про портативність.
Відповідно до розділу " Стандартний документ C " 6.3.2.3
:
Ціле постійне вираження зі значенням 0, або такий вираз, переданий типу void *, називається константою нульового покажчика.55) Якщо константа нульового покажчика перетворена в тип вказівника, отриманий вказівник, який називається нульовим покажчиком, є гарантовано порівняти нерівне вказівник з будь-яким об’єктом чи функцією.
Поки що я не бачив компілятора, який відірвався від цього.