здесь вообще.

ю этоEOF а также'\0' имеют целые числа типа, но если это так, не должны ли они иметь фиксированное значение?

Я напечатал оба и получил -1 дляEOF и 0 для'\0', Но фиксированы ли эти значения?

У меня тоже было это

int a=-1;

printf("%d",a==EOF); //printed 1

Являются ли значение дляEOF а также'\0' фиксированные целые числа?

 Martin York16 янв. 2011 г., 19:17
Примечание. Символ \ в символьном литерале обозначает escape-последовательность. Таким образом, '\ 0' является восьмеричной escape-последовательностью, значение которой равно 0.
 Keith Thompson11 июн. 2013 г., 20:36
В С,EOF а также'\0' являются выражениями типаint, Сказать, что они «типа целых чисел», не имеет большого смысла;int, long, unsigned char и так далее все целочисленные типы. (Хотя названиеint возникло как сокращение от «целое число», «целое число» в C является более всеобъемлющим термином, чемint.)

Ответы на вопрос(5)

NULL а также'\0' гарантированно равны 0, поэтому (с соответствующими приведениями) их можно считать идентичными по значению; заметьте, однако, что они представляют две совершенно разные вещи:NULL является нулевым (всегда недействительным)указатель, пока'\0' является ограничителем строкиEOF вместо этого - отрицательная целочисленная константа, которая указывает конец потока; часто это -1, но стандарт ничего не говорит о его фактической стоимости.

C & C ++ различаются по типуNULL а также'\0':

в C ++'\0' этоcharв то время как в C этоint; это потому, что в C все символьные литералы считаютсяints.

в C ++NULL "просто" целое число 0, в то время как в C его можно определить как 0, приведенный кvoid *; это не может быть сделано в C ++ (и это явно запрещено в примечании), потому что, будучи C ++ более строгим в преобразованиях указателей,void * не является неявно конвертируемым в любой другой тип указателя, поэтому, еслиNULL былvoid *, необходимо будет привести его к целевому типу указателя при назначении:

int * ptr = (void *) 0; /* valid C, invalid C++ */

Соответствующие стандартные цитаты:

C ++ 98/03NULL

NULL является целочисленным типом, гарантированно равным 0:

4.10 Преобразование указателя

Константа нулевого указателя - это целочисленное константное выражение (5.19) r целого типа, которое оценивается как ноль. Константа нулевого указателя может быть преобразована в тип указателя; результат является нулевым значением указателя этого типа и отличается от любого другого значения указателя на объект или указателя на тип функции. Два значения нулевого указателя одного типа должны сравниваться одинаково. Преобразование константы с нулевым указателем в указатель на cv-квалифицированный тип является одиночным преобразованием, а не последовательностью преобразования указателя, за которым следует преобразование квалификации (4.4).

18.1 Типы

[...] Макрос NULL является константой нулевого указателя C ++, определенной реализацией, в этом международном стандарте (4.10). (Возможные определения включают0 а также0L, но нет(void*)0).

'\0'

Должен существовать 0-значной символ:

2.2 Наборы символов

Базовый набор символов выполнения и базовый набор широких символов выполнения должны содержать [...] нулевой символ (соответственно нулевой широкий символ), представление которого имеет все нулевые биты.

'\0' этоchar буквальный:

2.13.2 Символьные литералы

Символьный литерал - это один или несколько символов, заключенных в одинарные кавычки, как в'x', необязательно, перед буквой L, как в L’x ’. Символьный литерал, который не начинается с L, является обычным символьным литералом, также называемым литералом с узким характером. Обычный символьный литерал, который содержит одинс-символ имеет типcharсо значением, равным числовому значению кодированияс-символ в наборе символов выполнения.

и его значение равно 0, так как эта escape-последовательность определяет его значение:

Побег\ooo состоит из обратной косой черты, за которой следуют одна, две или три восьмеричных цифры, которые взяты для указания значения нужного символа.

'\0' используется для завершения строковых литералов:

2.13.4 Строковые литералы

После любой необходимой конкатенации на этапе 7 перевода (2.1)'\0' добавляется к каждому строковому литералу, чтобы программы, сканирующие строку, могли найти ее конец.

EOF

ОпределениеEOF делегируется стандарту C89 (как указано в § 27.8.2 «Файлы библиотеки C»), где он определяется как отрицательное целое число, зависящее от реализации.

C99,NULL

Нулевой указатель представляет собой целое число 0, необязательно приведенное кvoid *; NULL нулевой указатель

6.3.2.3. Указатели

[...] Целочисленное константное выражение со значением 0 или такое выражение, приведенное к типуvoid *, называется константой нулевого указателя. (МакросNULL определяется в<stddef.h> (и другие заголовки) как константа нулевого указателя; см. 7.17.) Если константа нулевого указателя преобразуется в тип указателя, результирующий указатель, называемый нулевым указателем, гарантированно сравнивается с неравным указателем на любой объект или функцию.

7.17 Общие определения<stddef.h>

[...] Макросы

NULL

которая расширяется до определенной в реализации постоянной нулевого указателя; [...]

'\0'

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

5.2.1 Наборы символов

[...] Байт со всеми битами, установленными в 0, называетсянулевой символ, должен существовать в базовом наборе символов выполнения; он используется для завершения символьной строки.

6.4.4.4 Символьные константы

Целочисленная символьная константа - это последовательность из одного или нескольких многобайтовых символов, заключенных в одинарные кавычки, как в'x', [...]

Восьмеричные цифры, которые следуют за обратной косой чертой в восьмеричной escape-последовательности, считаются частью построения одного символа для целочисленной символьной константы или одного широкого символа для широкой символьной константы. Числовое значение восьмеричного восьмеричного целого числа указывает значение желаемого символа или широкого символа. [...]

Целочисленная символьная константа имеет типint.

EOF

EOF определенное реализацией отрицательное целое число

7.19 Ввод / вывод<stdio.h>

7.19.1 Введение

EOF

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

 Keith Thompson11 июн. 2013 г., 20:41
Приведенный выше комментарий является придиркой и не особенно актуален в большинстве случаев.
 Keith Thompson11 июн. 2013 г., 20:40
В С,NULL не обязательно оценивать0 после конвертации. ЕслиNULL определяется как((void*)0), тогда(int)NULL может или не может оценить0, Существует специальное правило для преобразования константного целочисленного выражения в тип указателя (это часть определенияконстанта нулевого указателя), но в обратном направлении такого правила нет. В редкой реализации, где нулевой указатель не представлен как все биты-ноль, преобразование нулевого указателя в целочисленный тип может дать вам ненулевое значение. НоNULL == 0 верно, потому что0 при необходимости преобразуется в указатель.

Да.'\0' имеет такое же значениеNULL который равен 0 (но они означают разные вещи), в то время как EOF обычно -1.

printf("%d",a==EOF); //printed 1

В этом случае вы спрашиваете: == EOF? если это print 1 (что верно), это не print 0 (что ложно).

 Matteo Italia16 янв. 2011 г., 15:52
'\0' а такжеNULL Может случиться так, что они всегда имеют одинаковое значение, но имеют совершенно другое значение.'\0' является ограничителем строки, в то время какNULL является нулевым (недействительным) указателем.
 BlackBear16 янв. 2011 г., 15:55
@matteo: да, я запутался. только что отредактировал;)
 theReverseFlick16 янв. 2011 г., 15:54
Но что, если есть требование провести различие между EOF и -1?
 BlackBear16 янв. 2011 г., 15:52
@ShyamLovesToCode: обычно так и есть.
 theReverseFlick16 янв. 2011 г., 15:51
Да, я просто хотел спросить, всегда ли EOF -1

EOF зависит от компилятора

чаще всего это -1 (в gcc & g ++ это -1).

 Konrad Rudolph16 янв. 2011 г., 16:12
@Charles\0 этоchar, Нет причиныNULL должно быть реализовано с точки зрения этого. Хотя это правда, что слабые правила преобразования C ++разрешать для этого это просто бессмысленно и ИМХО очень вводит в заблуждение в ответе на вопрос, какова ценность\0 является.
 Konrad Rudolph16 янв. 2011 г., 15:55
\0 являетсяникогда NULL (В С, первыйint и последний является указателем; в C ++ первыйchar и последний является int / pointer / char в зависимости от контекста). Я понимаю, что ваш ответ все еще строго верен в соответствии с булевой алгеброй, но он полностью вводит в заблуждение и любое упоминание оNULL как сделано здесь не имеет значения.
 CB Bailey16 янв. 2011 г., 15:59
@KonradRudolph: почему не могуNULL быть\0 в С ++? Казалось бы, правильное определение для меня. Интегральное постоянное выражение (проверка),Rvalue (проверить), оценивает в ноль (проверка).
 Konrad Rudolph16 янв. 2011 г., 16:14
@Christoph: «сравнивает равно» - это принципиально иное утверждение, чем «всегда». В частности, это артефакт слабой типизации C ++, а непричинный отношение, как подразумевается первоначальной формулировкой в ​​этом ответе. Я очень предпочитаю обновленный ответ: «\ 0» всегда 0 »- не нужно упоминатьNULL здесь вообще.
 Christoph16 янв. 2011 г., 15:58
@ Конрад: ты не прав:NULL оценивает константу нулевого указателя, определенную реализацией, то есть целочисленное константное выражение со значением 0, или - в C - такое выражение приведено кvoid *; '\0' является действительной константой нулевого указателя и сравнивается равнымNULL

«\ 0» всегда является нулевым символом или 0. но обычно равно -1, и всегда является значением, котороеunsigned char не могу удержаться Не полагайтесь на значение EOF, являющегося чем-то, потому что оно МОЖЕТ ИЗМЕНИТЬСЯ. Всегда делайте x == EOF, а не x == -1. Значение '\ 0' ВСЕГДА 0. Вы можете рассчитывать на это.

 Keith Thompson11 июн. 2013 г., 20:48
EOF имеет типint, Поскольку это отрицательно, по определению это значение, котороеunsigned char не могу удержаться Но так как это возможно дляunsigned char а такжеint иметь одинаковый размер (еслиCHAR_BIT >= 16), может быть невозможно различитьEOF и действительный результат отgetchar(), Это недостаток внутриполосной сигнализации. Но игнорировать это на 99,99% безопаснее, так как единственные реальные системы сCHAR_BIT >= 16 являются DSP, и вы не ожидаете, что портативный код ввода-вывода будет работать в такой системе в любом случае.
Решение Вопроса

EOF макрос, который расширяется до целочисленного константного выражения с типомint и зависящее от реализации отрицательное значение, но очень часто -1.

'\0' этоchar со значением 0 в C ++ иint со значением 0 в С.

Причина по которойprintf("%d",a==EOF); привело к1 потому что ты не присваивал значениеEOF вa, Вместо этого вы проверили, еслиa был равенEOF и так как это было правдой (a == -1 == EOF) это напечатано1.

 OrangeDog16 янв. 2011 г., 15:55
@Shyam - Почему такая необходимость? использованиеNULL если вы говорите об указателях,'\0' если вы говорите о персонажах и использоватьEOF при проверке конца файла. Это делает ваш код менее запутанным.
 OrangeDog17 янв. 2011 г., 00:13
@Shyam - я обычно используюINT_MIN в качестве недопустимого значения в этом случае. Это имеет приятный побочный эффект - сделать целые числа симметричными. Однако, если вам нужно иметь всеintВ качестве возможных значений вам понадобится структура с дополнительным флагом «недопустимый».
 CB Bailey16 янв. 2011 г., 16:02
@ShyamLovesToCode: если каждое целое число может принимать любое значение в пределах своего диапазона, то, по определению, никакое действительное целое число не может быть часовым значением. Если вы хотите сохранить флаг «не значение», вам придется сделать это с дополнительными элементами данных.
 James Greenhalgh16 янв. 2011 г., 16:14
Если требуется хранить какое-либо целочисленное значение, вам потребуется дополнительная структура данных. Если вы можете хранить практически любое целочисленное значение, вы можете использовать INT_MAX для обозначения неверных данных.
 CB Bailey16 янв. 2011 г., 15:54
@ShyamLovesToCode: Вы не можете различать 0 и NULL, потому что NULL может расшириться до 0. Я не понимаю, как и зачем вам это нужно, поясните?

Ваш ответ на вопрос