Это всегда казалось мне странный, что функция C "fopen" берет "символ константы *" в качестве второго аргумента. Я думал бы, что это было бы легче и прочитать Ваш код и реализовало бы код библиотеки, если бы были битовые маски, определенные в stdio.h, как "IO_READ" и такой, таким образом, Вы могли сделать вещи как:
FILE* myFile = fopen("file.txt", IO_READ | IO_WRITE);
Существует ли программная причина способа, которым это на самом деле, или это является просто историческим? (т.е. "Это - просто способ, которым это".)
Одно слово: наследие. К сожалению, нам приходится с этим жить.
Просто предположение: может быть, в то время «const char *» казался более гибким решением, потому что он никоим образом не ограничен. Битовая маска может иметь только 32 различных значения. Теперь мне кажется, что это ЯГНИ.
Еще больше предположений: чуваки были ленивы, и написание «rb» требует меньше набора текста, чем MASK_THIS | MASK_THAT :)
Как говорит Туомас Пелконен, это наследие.
Лично мне интересно, считали ли некоторые ошибочные сэпы, что это лучше из-за меньшего количества набранных символов? В старину время программистов ценилось выше, чем сегодня, поскольку оно было менее доступным, а компиляторы не такими хорошими и все такое.
Это всего лишь предположение, но я понимаю, почему некоторые люди предпочли бы сохранить несколько символов здесь и там (обратите внимание на отсутствие подробностей в именах стандартных библиотечных функций ... Я представляю string.h "strstr" и "strchr" как, наверное, лучший пример излишней краткости).
Я бы предположил, что это одно или несколько из следующих (к сожалению, мне не удалось быстро найти какие-либо подтверждающие ссылки, так что это, вероятно, останется предположением):
fopen ()
) просто случайно понравилась идея указания режима с использованием строки вместо растрового изображения open ()
интерфейс системного вызова, поэтому он будет сразу знаком, но не будет компилироваться по ошибке с константами, определенными для Unix, а не библиотекой C Например, предположим, что мифический стандарт C fopen ()
, которая приняла параметр режима побитового отображения, использовала идентификатор OPENMODE_READONLY
, чтобы указать, что файл, который сегодня указан в строке режима «r». Теперь, если бы кто-то сделал следующий вызов для программы, скомпилированной на платформе Unix (и что был включен заголовок, определяющий O_RDONLY
):
fopen( "myfile", O_RDONLY);
Не было бы ошибки компилятора, но если только не OPENMODE_READONLY
и O_RDONLY
были определены как один и тот же бит, при котором вы получите неожиданное поведение. Конечно, было бы разумно, чтобы стандартные имена C были определены так же, как имена Unix, но, возможно, они хотели исключить необходимость такой связи.
С другой стороны, это могло и не приходить им в голову ...
Деннис Ричи сказал следующее из http://cm.bell-labs.com/cm/cs/who/dmr/chist.html
В частности, Леск написал «портативный {{ 1}} Пакет ввода-вывода '[Lesk 72], который позже был переработан, чтобы стать C` стандартными процедурами ввода-вывода'
Так что я говорю: спросите Mike Lesk , опубликуйте результат здесь как ответ на свой вопрос и заработайте за это несколько очков. Хотя вы, возможно, захотите, чтобы вопрос звучал немного менее похоже на критику; -)
Я считаю, что одно из преимуществ символьной строки вместо простой битовой маски состоит в том, что она допускает специфичные для платформы расширения, которые не являются битовыми настройками. Чисто гипотетически:
FILE *fp = fopen("/dev/something-weird", "r+,bs=4096");
Для этой штуковины вызову open ()
нужно сообщить размер блока, а разные вызовы могут использовать радикально разные размеры и т. Д. Конечно, ввод-вывод организован довольно хорошо. сейчас (изначально этого не было - устройства были чрезвычайно разнообразны, а механизмы доступа далеки от унифицированных), поэтому в этом редко возникает необходимость. Но аргумент открытого режима со строковым значением обеспечивает такую расширяемость намного лучше.
На мэйнфреймах IBM MVS o / s функция fopen ()
действительно принимает дополнительные аргументы в соответствии с общими принципами, описанными здесь - как отметил Эндрю Хенле ] (Спасибо!). Страница руководства включает пример вызова (слегка переформатирован):
FILE *fp = fopen("myfile2.dat", "rb+, lrecl=80, blksize=240, recfm=fb, type=record");
Базовый open ()
должен быть дополнен вызовом ioctl ()
(управление вводом-выводом) или fcntl ()
(управление файлами) или функции, скрывающие их, для достижения аналогичных эффектов.
Я должен сказать, что благодарен за это - я знаю, что набирать "r" вместо IO_OPEN_FLAG_R или это был IOFLAG_R или SYSFLAGS_OPEN_RMODE или что-то еще