2010-06-02 5 views
19

Я пытался выяснить, почему C++ делает меня сумасшедшим, набрав NULL. Внезапно он бьет меня на днях; Я уже много лет набираю null (нижний регистр) на Java. Теперь я начинаю программировать на C++, и этот маленький кусок мышечной памяти делает меня сумасшедшим.В чем разница между NULL в C++ и null в Java?

Wikiperipatetic определяет C++ NULL как часть stddef:

макрокоманды, которая расширяется к нулевой константе указателя . Он может быть определен как ((void *) 0), 0 или 0L в зависимости от компилятора и языка.

документы Sun говорит мне это о Java в «нулевой буквальным»:

Нулевой тип имеет одно значение, нулевая ссылку, представленную буквального нулем, которая формируется из ASCII символов , Нулевой литерал всегда равен нулевого типа.

Так что это все очень приятно. Я знаю, что такое ссылка на нулевой указатель, и благодарю вас за комментарии к компилятору. Теперь я немного нечеткой на идее буквальным в Java, так что я читать ...

Буквальное исходный код представление фиксированного значения; литералы представлены непосредственно в ваш код, не требуя вычислений.

Существует также специальный пустой литерал , который может использоваться как значение для любого ссылочного типа . null может быть назначено для любой переменной, кроме переменных из примитивных типов. Мало что вам может сделать с нулевым значением за пределами тестирования на его присутствие. Поэтому null часто используется в программах как маркер , чтобы указать, что у какого-либо объекта недоступно.

Итак, я думаю, что я понял. В C++ NULL - это макрос, который при компиляции вычисляет константу нулевого указателя. В Java значение null является фиксированным значением, которое может быть присвоено любому не примитиву; отлично подходит для тестирования в удобном режиме if statement.

В Java нет указателей, поэтому я могу понять, почему они сохранили нулевое значение, а не что-то интересное. Но почему я решил изменить все колпачки NULL на null?

Кроме того, я что-то пропустил здесь?

+7

«Java не имеет указателей». На самом деле Java * only * имеет указатели. –

+1

За исключением базовых типов =) –

+1

'((void *) 0)' не является допустимым определением 'NULL' в C++. –

ответ

20

Яблочный символ null больше похож на nullpt C++ 0x. NULL в C++ - это всего лишь 0 и может в конечном итоге разрешить вместо int, а не указатель, как вы хотите. Рассмотрим:


void f(int); 
void f(char*); 

... 

f(NULL); // which f()? 

C++ 0x имеет nullptr, который фиксирует эту проблему, но она по-прежнему не будет полностью эквивалентна нулевой Java. Это просто разные языки.

О, и еще одно отличие заключается в том, что Java не имеет указателей (или так говорит). В Java вы можете законно присваивать значение null ссылке, в C++ вы не можете этого сделать, не используя уже плохо сформированную конструкцию. По общему признанию, Java будет рядом с бесполезной без этой способности, но это определенно еще одно важное различие.

+4

Ссылки на Java имеют некоторые свойства указателей C++ и некоторые свойства ссылок на C++, поэтому их трудно сравнивать напрямую. –

+2

Нет, Java 'null' абсолютно не похож на C++' nullptr' просто потому, что Java не имеет указателей, а 'nullptr' C++ строго специфичен для указателя. – AnT

+0

@ Тайлер - мне кажется, что они больше похожи на указатели, чем ссылки, по той причине, что они могут быть нулевыми. На самом деле единственный различие между java refs и C++ ptrs заключается в том, что вы не можете делать математику на них. Конечно, AFAIK Java на самом деле не рассматривает их как разные типы вообще, ссылку или указатель, в то время как C++ действительно делает. На самом деле два языка практически не похожи. –

23
  • NULL является препроцессора директивы идентификатор а, согласно конвенции, те должны быть все заглавные буквы.

  • null является язык litteral, представляющий постоянное значение и должно согласно конвенции быть все ниже (так же, как true или false).

+3

Хорошо встретился и хороший ответ. Теперь, любая идея, почему у них есть это соглашение? Вы знаете, что они должны были сидеть за столом, говоря об истинном/ложном/нулевом и думать ... «Хм, мы меняем нуль на них ...» – Stephano

+2

@Stephano Они, вероятно, не сидели вокруг, говоря об этом. «true» и «false» также являются строчными буквами на C++. Это довольно распространенное соглашение. Как только Java решила, что концепция «нет объекта здесь» была встроенной константой, ей необходимо следовать конвенции. Следовательно, «null». – moswald

+2

На самом деле не может быть никакого хорошего ответа, за исключением того, что все ключевые слова являются строчными. Возможно, они просто хотели подчеркнуть, что это не макрос какого-либо рода, а на самом деле часть спецификации языка. Честно говоря, я не думаю, что они думали об этом как о «изменении» от C++ NULL. – aioobe

2

Используйте 0 вместо NULL.

От «++ языка программирования C» книги создателя языка, Бьярня Страуструпа:

В C, он был популярен, чтобы определить макрос NULL для представления нулевого указателя. Из-за Более строгая проверка на C++, использование простого 0, а не любого предлагаемого макроса NULL, приводит к меньшему количеству проблем. Если вы считаете, что должны определить NULL, используйте const int NULL = 0;

+0

Ничего себе, очень интересно. Могу ли я сказать что-то вроде: (class) Node n = 0; ? – Stephano

+0

Это должно быть Node * n = 0, потому что 0 является (нулевым) указателем. Другими словами, поскольку ни один объект не может иметь адрес в памяти 0, 0 в этом случае указывает, что указатель указывает на отсутствие экземпляра класса Node. В противном случае было бы похоже, что вы пытаетесь присвоить узлу целое число. – metaliving

+1

Правильно, C++ NULL равен 0, тогда как C NULL чаще (void *) 0. –

1

В C++ NULL является макрос, который, когда скомпилирован, определяет нулевой указатель константу.

Здесь вы ошибаетесь. В C++ NULL равен 0, и больше ничего. Оба указателя и целые числа могут быть NULL.

В java, с другой стороны, null является нулевым указателем, что означает, что только объекты могут быть пустыми.

+0

Я бы не сказал, что это неправильно. 'NULL' - это макрос, который вычисляет константу нулевого указателя' 0'. Он не * определяет * контекст нулевого указателя, но я думаю, что это всего лишь вопрос двусмысленного выбора слова. –

+0

Это был плохой выбор слова. Я изменил его на «оценивает». – Stephano

+1

@both comments - Этот плакат правильный, и это важно отметить. NULL не является константой указателя, это интегральная константа. Похоже, что значение NULL равно 0, также оценивается нулевым указателем при использовании в контексте значения указателя. Как я упоминаю в своем собственном посте, но NULL будет решать целые числа перед указателем, потому что это то, что на самом деле. –

0

Ну, я не знаю, ПОЧЕМУ java решил изменить NULL на нуль, однако прописные буквы более сложны для ввода (по крайней мере, на мой взгляд). Но вы, вероятно, всегда можете спросить солнце: -P. В любом случае, если говорить, что java не имеет указателей, это не совсем верно, потому что нормальные ссылки в java или C# или подобных файлах больше похожи на указатели, чем на refferences в C++. Например, в C++ ссылка не может быть NULL, но ссылка в java может. И ссылка в C++ не может изменить, какую переменную она указывает (я могу ошибаться на этом этапе), но ссылка на java может.

2

Нет, вы в значительной степени его получили. В C++ нулевой указатель - это любое буквальное нулевое значение, которое назначается указателю. NULL - это просто макрос для 0, и поэтому ptr = 0 и ptr = NULL идентичны. Он включен только для удобства/удобочитаемости. Причина, по которой это заглавная, состоит в том, что в C и C++ существует давнее соглашение, что имена макросов должны быть прописными.

В Java null является встроенным литералом, и поскольку он не является макросом (и Java не имеет понятия макроса в любом случае), нет веской причины сделать его прописным.

6

Что касается вашего последнего вопроса, я не уверен, что обоснование дизайна находится за нижним регистром null, , но я думаю, что целью было сделать пустой литерал на уровне языка (например, true или false), а не константу.

Ключевые слова в java, как правило, имеют нижний регистр и поэтому называются литералами. Константы (например, Integer.MAX_VALUE) обычно имеют верхний регистр.

+0

+1 Также хороший ответ. Мне нужно было искать кучу констант, но казалось бы, что они в основном в верхнем регистре. Интересный момент. – Stephano

+5

В качестве комментария я хотел бы указать, что C не имеет «истинных» или «ложных», но файлы заголовков обычно «#define TRUE 1» и «#define FALSE 0». C 'NULL' соответствует этой схеме. –

1

В Java нет указателей, как вы сказали сами, поэтому концепция «null» совершенно несравнима между Java и C++.

Ваш вопрос имеет такое же значение, как «в чем разница между углом и яблоком», то есть он не может быть отвечен каким-либо другим способом, кроме очевидного: NULL в C++ и null на Java - это два полностью и совершенно не связанные понятия.

Java никогда "решил" изменить все заглавные буквы NULL на null, потому что, опять же, в Java null не имеет никакого отношения к C++ 's NULL.

+2

С другой стороны, Java - это главным образом указатели, и поэтому концепции очень близки. –

+0

Андрей: Это строго верно, но практически ложно. Вы правы, что Java не хватает указателей, как таковых, но его ссылки очень похожи на указатели C/C++. –

0

Указатели - это в основном адреса памяти. И есть только один известный и установленный адрес памяти, 0. CULL NULL капитализируется, потому что это макрос препроцессора, и они всегда капитализируются по соглашению. Концепция указателя непосредственно связана с понятием адресного пространства в аппаратном обеспечении.

Java использует ссылки и имеет собственный внутренний способ их представления. Существует одна известная ссылка, null. Это в нижнем регистре, потому что это в основном другой символ, хотя и ссылающийся на буквальное значение. Я не думаю, что они «изменили» что-либо с C на Java. Я думаю, они просто хотели нулевую концепцию, поэтому они назвали ее «нулевой».

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

+1

Использование 0 для нулевого указателя в C и C++ не основано на идее о том, что ячейка памяти 0 является специальной, хотя так обычно ее реализуют. Постоянный интеграл 0 будет передан в константу нулевого указателя. –

+0

Я не говорю, что ячейка памяти 0 является специальной, просто, что она хорошо известна и используется как соглашение, чтобы сказать, что указатель не является допустимым адресом. – Vagrant

2

Ключевое слово Java null используется для идентификации переменной как ссылки на какой-либо объект. Ключевое слово null нельзя назначить переменной, объявленной с помощью примитивного типа данных. Значение NULL C++ является константой, которая определена как 0.

Смежные вопросы