kzen.dev
  • Вопросы
  • Метки
  • Пользователи
Оповещения
Вознаграждения
Регистрация
После регистрации, сможете получать уведомления об ответах и комментариях на Ваши вопросы.
Вход
Если у Вас уже есть аккаунт, войдите чтобы проверить новые уведомления.
Тут будут вознаграждения за добавленные вопросы, ответы и комментарий.
Дополнительно
Источник
Редактировать
 gnavi
gnavi
Вопрос

В чем разница между NULL, '\0' и 0

В языке C существуют различия между различными значениями нуля - NULL, NUL и 0.

Я знаю, что ASCII символ '0' оценивается как 48 или 0x30.

Указатель NULL обычно определяется как:

#define NULL 0

Или

#define NULL (void *)0

Кроме того, существует символ NUL '\0', который, похоже, также оценивается в 0.

Бывают ли случаи, когда эти три значения не могут быть равны?

Это также верно для 64-битных систем?

285 2009-08-18T22:09:59+00:00 11
too  honest for this site
too honest for this site
Редактировал вопрос 14-го ноября 2016 в 8:42
Программирование
null
c
pointers
Решение / Ответ
Andrew Keeton
Andrew Keeton
18-го августа 2009 в 10:14
2009-08-18T22:14:45+00:00
Дополнительно
Источник
Редактировать
#9384908

Примечание: Этот ответ относится к языку C, а не к C++.


Нулевые указатели

Литерал целочисленной константы 0 имеет различные значения в зависимости от контекста, в котором он используется. Во всех случаях это по-прежнему целочисленная константа со значением 0, просто она описывается по-разному.

Если указатель сравнивается с литералом константы 0, то это проверка, не является ли указатель нулевым. Тогда 0 называется константой нулевого указателя. Стандарт C определяет, что 0, приведенный к типу void *, является и нулевым указателем, и константой нулевого указателя.

Кроме того, для облегчения чтения в заголовочном файле stddef.h предусмотрен макрос NULL. В зависимости от вашего компилятора может быть возможно #undef NULL и переопределить его на что-то странное.

Поэтому ниже приведены некоторые правильные способы проверки нулевого указателя:

if (pointer == NULL)

NULL определено для сравнения с нулевым указателем. Реализация определяет, каково фактическое определение NULL, пока это допустимая константа нулевого указателя.

if (pointer == 0)

0 - это другое представление константы нулевого указателя.

if (!pointer)

Это утверждение if неявно проверяет "не 0", поэтому мы перевернем его, чтобы оно означало "есть 0".

Следующие способы проверки нулевого указателя являются НЕПРАВИЛЬНЫМИ:

int mynull = 0;
<some code>
if (pointer == mynull)

Для компилятора это не проверка нулевого указателя, а проверка равенства двух переменных. Это может работать, если mynull никогда не изменяется в коде и оптимизация компилятора постоянно складывает 0 в оператор if, но это не гарантировано, и компилятор должен выдать хотя бы одно диагностическое сообщение (предупреждение или ошибку) в соответствии со стандартом C.

Обратите внимание на то, что является нулевым указателем в языке Си. Это не зависит от базовой архитектуры. Если в базовой архитектуре значение нулевого указателя определено как адрес 0xDEADBEEF, то разбираться с этой неразберихой придется компилятору.

Таким образом, даже на этой забавной архитектуре следующие способы проверки нулевого указателя все еще действительны:

if (!pointer)
if (pointer == NULL)
if (pointer == 0)

Следующие способы проверки нулевого указателя являются НЕПРАВИЛЬНЫМИ:

#define MYNULL (void *) 0xDEADBEEF
if (pointer == MYNULL)
if (pointer == 0xDEADBEEF)

поскольку компилятор воспринимает их как обычные сравнения.

Нулевые символы

'\0' определяется как нулевой символ, то есть символ, все биты которого равны нулю. Это не имеет никакого отношения к указателям. Однако вы можете увидеть что-то похожее на этот код:

if (!*string_pointer)

проверяет, указывает ли указатель строки на нулевой символ

if (*string_pointer)

проверяет, указывает ли указатель строки на ненулевой символ

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

Кроме того, '\0' является (как и все символьные литералы) целочисленной константой, в данном случае со значением ноль. Таким образом, '\0' полностью эквивалентен целочисленной константе 0 без прикрас - разница лишь в намерении, которое он передает читателю ("Я использую это как нулевой символ.").

Ссылки

См. подробнее Вопрос 5.3 из FAQ по comp.lang.c. Смотрите этот pdf для стандарта C. Посмотрите разделы 6.3.2.3 Указатели, параграф 3.

 Zitrax
Zitrax
Редактировал ответ 24-го октября 2016 в 8:27
332
0
 amaterasu
amaterasu
18-го августа 2009 в 10:48
2009-08-18T22:48:27+00:00
Дополнительно
Источник
Редактировать
#9384914

Представляется, что количество людей понимают, что различия между null, '\0' и 0. Так, чтобы объяснить, и в попытке избежать повторения сказанного ранее:

Константное выражение типа int со значением 0, или такое выражение такого типа приводится к типу Void * - это константа нулевого указателя, что если преобразовать в указатель становится указатель. Это гарантируется стандартом для сравнения неравный любой указатель на любой объект или функцию.

Нуль это макрос, определенный в <stddef.ч> в качестве константа нулевого указателя.

'\0' это конструкция, предназначенная для представления символ, используется для завершения строки.

А символ - это байт, который имеет все биты установлены в 0.

33
0
 Nasko
Nasko
18-го августа 2009 в 10:32
2009-08-18T22:32:14+00:00
Дополнительно
Источник
Редактировать
#9384912

Все три определения понятия ноль в другом контексте.

  • указатель контекста - использовать значение null и означает, что значение указателя равно 0, независимо от того, является 32-битной или 64 (в одном случае 4 байта остальные 8 байт нулей).
  • строковом контексте - персонаж, представляющий цифра ноль имеет шестнадцатеричное значение 0x30, в то время как нулевой символ имеет шестнадцатеричное значение от 0x00 (используется для завершения строки).

Эти трое всегда по-разному, когда вы смотрите на память:

NULL - 0x00000000 or 0x00000000'00000000 (32 vs 64 bit)
NUL - 0x00 or 0x0000 (ascii vs 2byte unicode)
'0' - 0x20

Я надеюсь, что это проясняет его.

chux  - Reinstate Monica
chux - Reinstate Monica
Редактировал ответ 22-го сентября 2017 в 7:27
14
0
Sinan &#220;n&#252;r
Sinan Ünür
18-го августа 2009 в 10:38
2009-08-18T22:38:25+00:00
Дополнительно
Источник
Редактировать
#9384913

Если значение null и 0 эквивалентны в качестве нулевого указателя-константы, которые я должен использовать? в с адресами, список часто задаваемых вопросов этой проблемы, а также:

в программисты должны понимать, что нуль и 0 являются взаимозаменяемыми в В контекстах указатель, и что uncast 0 > есть вполне приемлемо. Любое использование нуль (в отличие от 0) должны быть считается мягким напоминанием о том, что указатель участвует; программисты не должны зависеть от нее (либо на их собственное понимание или компилятор'ы) для различения указатель 0's и целое число 0'ов.

Это только в контексте указатель нуль и 0 эквивалентны. Нуль должны не используются, когда другой вид 0 - это требуется, даже если он может работать, так как это посылает неверный стилистические сообщение. (Кроме того, стандарт ANSI позволяет определять значение null, чтобы быть ((недействительными *)0), которая не будет работать на Все в non-указатель контекстов.) В В частности, не используйте нуль, когда ASCII с нулевым символом (нуль) требуется. обеспечить собственное определение

#define NUL '\0'

если вам необходимо.

6
0
Eugene Yokota
Eugene Yokota
18-го августа 2009 в 11:29
2009-08-18T23:29:39+00:00
Дополнительно
Источник
Редактировать
#9384915

В чем разница между null, ‘\0’ и 0

на "нулевой символ (нуль)" это простой, чтобы исключить. &#39;\0&#39; является символьным литералом. В C, это реализовано как инт, таким образом, это'ы такой же, как 0, который имеет INT_TYPE_SIZE. В C++, символьный литерал реализуется как Чара, который является 1 байт. Это, как правило, отличается от нуля или 0.

Далее, null является значением указателя, который указывает, что переменная не указывает ни на какой адресного пространства. Выделить тот факт, что он обычно реализуется как нули, он должен иметь возможность выразить полное адресное пространство архитектуры. Таким образом, на 32-разрядной архитектуре нуль (скорее всего) - это 4 байта, а в 64-битной архитектурой 8-байт. Это до реализации С.

Наконец, литерал 0 имеет тип int, который имеет INT_TYPE_SIZE размер``. Значение по умолчанию-INT_TYPE_SIZE может быть различным в зависимости от архитектуры.

Яблоко писал:

В 64-битной моделью данных, используемых в Mac OS Х известен как"LP64 &quot и;. Это общая модель данных, используемую для других 64-битных системах Unix от Sun и SGI, а также 64-битной Linux. Модель данных LP64 определяет примитивные типы следующим образом:

  • Интс являются 32-разрядными
  • тоскует являются 64-разрядными
  • долгосрочные лонги тоже 64-битный
  • указатели являются 64-разрядными

Википедия 64 бит:

Майкрософт'компилятор с++ ВК использует модель LLP64.

64-bit data models
Data model short int long  long long pointers Sample operating systems
LLP64      16    32  32    64        64       Microsoft Win64 (X64/IA64)
LP64       16    32  64    64        64       Most Unix and Unix-like systems (Solaris, Linux, etc.)
ILP64      16    64  64    64        64       HAL
SILP64     64    64  64    64        64       ?

Редактировать: Добавил еще на символьный литерал.

#include <stdio.h>

int main(void) {
    printf("%d", sizeof('\0'));
    return 0;
}

Приведенный выше код возвращает 4 на ССЗ и 1 на G++.

Eugene Yokota
Eugene Yokota
Редактировал ответ 19-го августа 2009 в 2:35
5
0
 EvilTeach
EvilTeach
19-го августа 2009 в 12:22
2009-08-19T00:22:11+00:00
Дополнительно
Источник
Редактировать
#9384916

Один я нуль, он заканчивается строкой.

Два-л значение null указывает на не вещь.

И я ставлю золотой бык

Что нет три-л NULLL.

https://stackoverflow.com/questions/220423/how-do-you-deal-with-nul

 Community
Community
Редактировал ответ 23-го мая 2017 в 11:33
4
0
 dlmeetei
dlmeetei
4-го ноября 2013 в 6:16
2013-11-04T06:16:37+00:00
Дополнительно
Источник
Редактировать
#9384917

Одна хорошая вещь, которая помогает мне, когда начиная с C(взято из экспертов по программированию на C за счет липы)

Отель One 'Я' нул и двух 'Я' нуль

Запомнить этот маленький стишок, чтобы вспомнить правильную терминологию для указателей и ASCII ноль:

The one "l" NUL ends an ASCII string,

The two "l" NULL points to no thing.

Apologies to Ogden Nash, but the three "l" nulll means check your spelling. 

Символ ASCII с битовым шаблоном ноль называется, А "нуль" по. Специальное значение указателя, которое значит, стрелка нигде не является "нуль" по. Эти два термина не являются взаимозаменяемыми в смысл.

 dlmeetei
dlmeetei
Редактировал ответ 1-го октября 2017 в 10:13
4
0
 peterb
peterb
18-го августа 2009 в 10:16
2009-08-18T22:16:47+00:00
Дополнительно
Источник
Редактировать
#9384910

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

В ANSI C нулевой указатель определяется как целочисленное значение 0. Поэтому любой мир, где это не так, не соответствует ANSI C.

2
0
John Millikin
John Millikin
18-го августа 2009 в 10:15
2009-08-18T22:15:12+00:00
Дополнительно
Источник
Редактировать
#9384909

NULL не гарантированно равен 0 - его точное значение зависит от архитектуры. Большинство основных архитектур определяют его как (void*)0.

'\0' всегда будет равно 0, потому что именно так кодируется байт 0 в символьном литерале.

Я не помню, обязаны ли компиляторы Си использовать ASCII - если нет, то '0' может не всегда равняться 48. В любом случае, маловероятно, что вы когда-нибудь столкнетесь с системой, использующей альтернативный набор символов, такой как EBCDIC, если только вы не работаете над очень непонятными системами.

Размеры различных типов будут отличаться на 64-битных системах, но целочисленные значения будут одинаковыми.


Некоторые комментаторы выразили сомнение в том, что NULL должен быть равен 0, но не быть нулем. Вот пример программы, а также ожидаемый вывод на такой системе:

#include <stdio.h>

int main () {
    size_t ii;
    int *ptr = NULL;
    unsigned long *null_value = (unsigned long *)&ptr;
    if (NULL == 0) {
        printf ("NULL == 0\n"); }
    printf ("NULL = 0x");
    for (ii = 0; ii < sizeof (ptr); ii++) {
        printf ("%02X", null_value[ii]); }
    printf ("\n");
    return 0;
}

Эта программа может вывести:

NULL == 0
NULL = 0x00000001
John Millikin
John Millikin
Редактировал ответ 18-го августа 2009 в 10:59
0
0
 richardtallent
richardtallent
18-го августа 2009 в 10:19
2009-08-18T22:19:26+00:00
Дополнительно
Источник
Редактировать
#9384911

Байт со значением 0х00 является, по таблице ASCII, специальный символ, называемый "нуль" или "нуль" по. В C, так как вы должны'т добавьте управляющие символы в исходном коде, это представлено в C строки со сбежавшим 0, т. е. " и\0" по.

Но истинный нуль не значение. Это отсутствие значения. Для указателя, это означает, что указатель не имеет ничего указывать. В базе данных, это означает, что нет никакого значения в поле (что не то же самое, что поле пустое, 0, или заполнены с пробелами).

В реальной значение данной системы и базы данных формат файла используется для обозначения нулевой разве'т должен 0х00.

0
0
 shinxg
shinxg
20-го сентября 2017 в 8:41
2017-09-20T08:41:10+00:00
Дополнительно
Источник
Редактировать
#9384918

(недействительными*) 0 является нулем, и '\0' обозначает конец строки.

-2
0
Добавить вопрос
Категории
Все
Технологий
Культура / Отдых
Жизнь / Искусство
Наука
Профессии
Бизнес
Пользователи
Все
Новые
Популярные
1
Денис Васьков
Зарегистрирован 16 часов назад
2
Dima Patrushev
Зарегистрирован 2 дня назад
3
sirojidddin otaboyev
Зарегистрирован 1 неделю назад
4
Елена Гайдамамакинат
Зарегистрирован 1 неделю назад
5
Иван Степанюк
Зарегистрирован 1 неделю назад
DE
ES
ID
JA
KO
RO
RU
TR
ZH
© kzen.dev 2023
Источник
stackoverflow.com
под лицензией cc by-sa 3.0 с атрибуцией