2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Эта тема закрыта, вы не можете редактировать и оставлять сообщения в ней. На страницу Пред.  1, 2, 3  След.
 
 Re: Смысл EOF в си
Сообщение11.12.2012, 01:05 


11/12/12
1
Joker_vD в сообщении #595331 писал(а):
Вообще-то EOF вводится по Ctrl+D (UNIX) / Ctrl+Z (Win). Ctrl+C — это прерывание работы программы. ...


СПАСИБО.

 Профиль  
                  
 
 Re: Смысл EOF в си
Сообщение03.11.2021, 09:30 
Аватара пользователя


28/10/21
99
venco в сообщении #595763 писал(а):
Ребята, давайте не путать ТС. EOF в C - константа всегда равная -1.


(В соседнем форуме кто-то недавно сослался на этот старинный тред и был введен в заблуждение тем, что он тут прочитал)

Во-первых, нет, EOF в стандартной библиотеке - отрицательное значение, константа типа int. Оно может быть равно какому угодно отрицательному значению типа int. Разумеется, первым приходящим в голову вариантом является именно -1 , по каковой причине в реализациях вы как правило увидите именно его. Однако ни С, ни POSIX не гарантируют такого значения. Можно найти примеры экзотических реализацией с -2.

Во-вторых, на уровне исходного кода это просто не имеет значения. Вас не должно интересовать, чему равно EOF, ибо проверку на EOF вы все равно будет делать всегда в рамках именно типа int и либо прямым сравнением с именованной константой EOF, либо проверкой на отрицательность. То есть конкретное числовое значение вас интересовать не будет вообще. А за попытки проверки на конец файла через явное сравнение с -1, как и за попытки пихать это значение в signed char (ибо "-1 обязательно поместится") вы получите сочного пендаля и по параболической траектории улетите подметать улицы, без права когда либо еще быть подпущенным к С-коду (я несколько утрирую, но лишь для того, чтобы лучше донести суть).

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

-- 02.11.2021, 22:41 --

Portnov в сообщении #595755 писал(а):
EOF как символ (например, Ctrl-D) имеет смысл при чтении данных из источника, в котором нет «естественного» конца. Например, с клавиатуры. Как определить, что ввод с клавиатуры закончен? Может, пользователь просто задумался? Так что нужен какой-то сигнал «Конец ввода».


Комбинация Ctrl-D в POSIX системах сама по себе не имеет никакого отношения к EOF и не является символом EOF.

Комбинация Ctrl-D - это все лишь команда терминала, которая заставляет терминал протолкнуть накопленный на этот момент буфер ввода во входной поток ожидающего этого ввода процесса. Ожидающий ввода процесс ожидает завершения функции read() на входном потоке. Комбинация Ctrl-D всего лишь вызывает досрочное завершение функции read(). Функция read() при этом возвращает количество байтов, которое она успела прочитать до момента нажатия Ctrl-D. В этом и заключается вся суть комбинации Ctrl-D - вызвать досрочное завершение функции read(). Больше ничего. Ни о каком EOF комбинация Ctrl-D не знает и никакого отношения к EOF не имеет.

Однако в POSIX действует соглашение, согласно которому, если функция read() вернула 0 (то есть ей не удалось прочитать ни одного байта), то это означает достижение конца файла. По этой причине вы можете косвенно использовать комбинацию Ctrl-D для искусственного создания ситуации EOF: когда процесс начал ожидать ввода через read(), вам нужно ничего не вводя сразу нажать Ctrl-D. Функция read() сразу завершится и вернет 0, что будет расценено, как конец файла.

По этой причине, когда терминал работает в режиме построчной буферизации, комбинация Ctrl-D расценивается как EOF только если вы нажмете ее в самом начале строки. Если вы нажмете Ctrl-D, когда в строке что-то уже набрано, никакого EOF не получится. Набранный буфер будет просто передан ждущему приложению, функция read() вернет положительное значение и всё.

 Профиль  
                  
 
 Re: Смысл EOF в си
Сообщение03.11.2021, 11:01 
Заблокирован


19/02/13

2388
TheRuinedMap в сообщении #1537513 писал(а):
попытки проверки на конец файла через явное сравнение с -1


Однако это работает, и работает успешно.

 Профиль  
                  
 
 Re: Смысл EOF в си
Сообщение03.11.2021, 11:11 
Аватара пользователя


28/10/21
99
Vladimir-80 в сообщении #1537528 писал(а):
TheRuinedMap в сообщении #1537513 писал(а):
попытки проверки на конец файла через явное сравнение с -1


Однако это работает, и работает успешно.


Почему это работает, я объяснил выше. Это, однако, совсем не означает, что так нужно делать. Шурупы, забитые молотком, тоже какбэ держатся...

 Профиль  
                  
 
 Re: Смысл EOF в си
Сообщение03.11.2021, 11:52 
Заблокирован


19/02/13

2388
TheRuinedMap в сообщении #1537529 писал(а):
Это, однако, совсем не означает, что так нужно делать.


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

 Профиль  
                  
 
 Re: Смысл EOF в си
Сообщение03.11.2021, 12:27 
Заслуженный участник


09/05/12
25179
Vladimir-80 в сообщении #1537537 писал(а):
Зачем усложнять? Чем проще - тем лучше.
Выше же уже максимально подробно объяснили: в другой реализации это может быть не так. В итоге вы получите программу, которая на другой платформе "почему-то" перестанет корректно работать.

 Профиль  
                  
 
 Re: Смысл EOF в си
Сообщение03.11.2021, 12:40 
Заблокирован


19/02/13

2388
И там же такие случаи охарактеризованы как экзотические.

 Профиль  
                  
 
 Re: Смысл EOF в си
Сообщение03.11.2021, 13:04 
Заслуженный участник


09/05/12
25179
Vladimir-80 в сообщении #1537549 писал(а):
И там же такие случаи охарактеризованы как экзотические.
Так ведь именно экзотические случаи и создают 99% проблем с совместимостью. :-)

Хотя даже при их полном отсутствии EOF лучше: код желательно писать так, чтобы он был понятным, и в этом случае видно, что это именно проверка достижения конца файла, а не сравнение чего-то с чем-то. Экономить один байт исходника себе дороже.

 Профиль  
                  
 
 Re: Смысл EOF в си
Сообщение03.11.2021, 17:44 
Аватара пользователя


28/10/21
99
Vladimir-80 в сообщении #1537537 писал(а):
TheRuinedMap в сообщении #1537529 писал(а):
Это, однако, совсем не означает, что так нужно делать.


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


Во-первых, как я ясно даль понять выше, нет никакого -1. Значение может быть любым.

Во-вторых, сравнение с EOF - это и есть "проще и лучше": элегантный самодокументирующийся код. Даже если бы в спецификации гарантировалась -1, все равно никто бы не сравнивал с -1. Мы бы все равно вручную определяли именованную константу с таким (или аналогичным) именем специально для того, чтобы сравнивать именно с ней. Ибо сравнение с магической константой - это режущий глаз ярко выраженный "овнокот".

 Профиль  
                  
 
 Re: Смысл EOF в си
Сообщение03.11.2021, 19:08 
Заблокирован


19/02/13

2388
TheRuinedMap в сообщении #1537592 писал(а):
Мы бы все равно вручную определяли именованную константу с таким (или аналогичным) именем специально для того, чтобы сравнивать именно с ней.


На мой субъективный взгляд все эти именованные константы - лишние сущности. Ширмочки, лишь декорирующие самую суть. А ведь суть важнее формы её подачи.
С NULL, кстати, та же история, что и с EOF. И с TRUE, и с FALSE тоже...

 Профиль  
                  
 
 Re: Смысл EOF в си
Сообщение03.11.2021, 19:27 
Аватара пользователя


14/12/17
1472
деревня Инет-Кельмында
Vladimir-80

Когда то давно я сталкивался с кодом под win32, который следовал правилу: если параметр численно равен нулю, то 0 и писать, символ, число, указатель, FALSE, не важно, всегда 0. В-общем, не советую так делать, если не хотите, чтобы вас вспоминали недобрым словом.

 Профиль  
                  
 
 Re: Смысл EOF в си
Сообщение03.11.2021, 19:42 
Заблокирован


19/02/13

2388
Ноль есть ноль - зачем его маскировать? Именованная константа - это дополнительная операция расшифровки, как для компилятора, так и для программиста. Железо ведь не знает никакого FALSE, для железа есть 0 в электрическом его воплощении. Чем ближе ход мысли программиста к "железячным" процессам, тем лучше. Опять же, на мой субъективный взгляд.

 Профиль  
                  
 
 Re: Смысл EOF в си
Сообщение03.11.2021, 19:51 


14/01/11
2918
С таким подходом лучше всего писать сразу в машинных кодах, правда, могут возникнуть сложности с портируемостью.

 Профиль  
                  
 
 Re: Смысл EOF в си
Сообщение03.11.2021, 19:59 
Аватара пользователя


28/10/21
99
Vladimir-80 в сообщении #1537611 писал(а):
Ноль есть ноль - зачем его маскировать? Именованная константа - это дополнительная операция расшифровки, как для компилятора, так и для программиста. Железо ведь не знает никакого FALSE, для железа есть 0 в электрическом его воплощении. Чем ближе ход мысли программиста к "железячным" процессам, тем лучше. Опять же, на мой субъективный взгляд.


Классическое заблуждение, проистекающее из необоснованных попыток "машинизировать" исходный текст программ на С или С++.

Железо не умеет выполнять С или С++ код. Железо будет выполнять тот машинный код, который предоставит ему компилятор. А там уже не будет никакого "нуля" на месте нулевых указателей, а будет зависящее от реализации (и от указательного типа!) внутреннее представление нулевого указателя, то есть может быть 0x0, может быть 0xFFFFFFFFF, может быть 0xBAADF00D, может быть что угодно.

Именно поэтому в реальности все с точностью до наоборот: именно явный 0 в исходном коде программы НЕ отражает реального положения дел, а лишь сбивает с толку. А NULL, хоть за ним формально и прячется тот же 0 - отражает суть намного лучше. Абсолютно та же самая история и с -1 в качестве EOF, с той только разницей, что работоспособность 0 в качестве null pointer constant гарантируется спецификацией языка, а -1 в качестве EOF - это вообще ни на чем не держащееся непонятно что.

 Профиль  
                  
 
 Re: Смысл EOF в си
Сообщение03.11.2021, 20:01 
Заблокирован


19/02/13

2388
Sender в сообщении #1537613 писал(а):
лучше всего писать сразу в машинных кодах


Именно! Ну или на ассемблере хотя бы.

Sender в сообщении #1537613 писал(а):
сложности с портируемостью


Это да, под каждую машину могут потребоваться модификации. Зато всё будет работать очень быстро, очень надёжно и с минимальными требованиями к ресурсам! Красота же, правда?

-- 03.11.2021, 20:11 --

TheRuinedMap в сообщении #1537614 писал(а):
там уже не будет никакого "нуля" на месте нулевых указателей, а будет зависящее от реализации внутреннее представление нулевого указателя, то есть может быть 0x0, может быть 0xFFFFFFFFF, может быть 0xBAADF00D, может быть что угодно.


Что такого эдакого может быть при реализации if (a-b)...? Если a и b равны, их разность всегда будет равна 0 - в электрическом его представлении.
Если мы договорились последним байтом файла ставить -1, то при корректном формате файла в его конце -1 и будет. Если нам зачем-то понадобилось отступить от этого правила, давайте просто озвучим изменение в документации и учтём его в работе.
Я злой и страшный серый волк противник всяческих излишеств и украшательств, я за чистоту помыслов и прозрачность поступков...

-- 03.11.2021, 20:14 --

TheRuinedMap в сообщении #1537614 писал(а):
А там уже не будет никакого "нуля" на месте нулевых указателей


Нулевой указатель, кстати, тоже весьма сомнительная концепция. Он ничем не лучше просто неинициализированного указателя. Ни тем, ни другим пользоваться нельзя ведь.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Эта тема закрыта, вы не можете редактировать и оставлять сообщения в ней.  [ Сообщений: 43 ]  На страницу Пред.  1, 2, 3  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group