Почему C “fopen” берет “символ константы *” в качестве его второго аргумента?

Это всегда казалось мне странный, что функция C "fopen" берет "символ константы *" в качестве второго аргумента. Я думал бы, что это было бы легче и прочитать Ваш код и реализовало бы код библиотеки, если бы были битовые маски, определенные в stdio.h, как "IO_READ" и такой, таким образом, Вы могли сделать вещи как:

FILE* myFile = fopen("file.txt", IO_READ | IO_WRITE);

Существует ли программная причина способа, которым это на самом деле, или это является просто историческим? (т.е. "Это - просто способ, которым это".)

14
задан usr2564301 10 July 2018 в 18:43
поделиться

6 ответов

Одно слово: наследие. К сожалению, нам приходится с этим жить.

Просто предположение: может быть, в то время «const char *» казался более гибким решением, потому что он никоим образом не ограничен. Битовая маска может иметь только 32 различных значения. Теперь мне кажется, что это ЯГНИ.

Еще больше предположений: чуваки были ленивы, и написание «rb» требует меньше набора текста, чем MASK_THIS | MASK_THAT :)

6
ответ дан 1 December 2019 в 10:18
поделиться

Как говорит Туомас Пелконен, это наследие.

Лично мне интересно, считали ли некоторые ошибочные сэпы, что это лучше из-за меньшего количества набранных символов? В старину время программистов ценилось выше, чем сегодня, поскольку оно было менее доступным, а компиляторы не такими хорошими и все такое.

Это всего лишь предположение, но я понимаю, почему некоторые люди предпочли бы сохранить несколько символов здесь и там (обратите внимание на отсутствие подробностей в именах стандартных библиотечных функций ... Я представляю string.h "strstr" и "strchr" как, наверное, лучший пример излишней краткости).

0
ответ дан 1 December 2019 в 10:18
поделиться

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

  1. Керниган или Ричи (или кто-то еще с интерфейсом для fopen () ) просто случайно понравилась идея указания режима с использованием строки вместо растрового изображения
  2. . Возможно, они хотели, чтобы интерфейс был похож на интерфейс Unix, но заметно отличался от него. open () интерфейс системного вызова, поэтому он будет сразу знаком, но не будет компилироваться по ошибке с константами, определенными для Unix, а не библиотекой C

Например, предположим, что мифический стандарт C fopen () , которая приняла параметр режима побитового отображения, использовала идентификатор OPENMODE_READONLY , чтобы указать, что файл, который сегодня указан в строке режима «r». Теперь, если бы кто-то сделал следующий вызов для программы, скомпилированной на платформе Unix (и что был включен заголовок, определяющий O_RDONLY ):

fopen( "myfile", O_RDONLY);

Не было бы ошибки компилятора, но если только не OPENMODE_READONLY и O_RDONLY были определены как один и тот же бит, при котором вы получите неожиданное поведение. Конечно, было бы разумно, чтобы стандартные имена C были определены так же, как имена Unix, но, возможно, они хотели исключить необходимость такой связи.

С другой стороны, это могло и не приходить им в голову ...

4
ответ дан 1 December 2019 в 10:18
поделиться

Деннис Ричи сказал следующее из http://cm.bell-labs.com/cm/cs/who/dmr/chist.html

В частности, Леск написал «портативный {{ 1}} Пакет ввода-вывода '[Lesk 72], который позже был переработан, чтобы стать C` стандартными процедурами ввода-вывода'

Так что я говорю: спросите Mike Lesk , опубликуйте результат здесь как ответ на свой вопрос и заработайте за это несколько очков. Хотя вы, возможно, захотите, чтобы вопрос звучал немного менее похоже на критику; -)

3
ответ дан 1 December 2019 в 10:18
поделиться

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

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 () (управление файлами) или функции, скрывающие их, для достижения аналогичных эффектов.

4
ответ дан 1 December 2019 в 10:18
поделиться

Я должен сказать, что благодарен за это - я знаю, что набирать "r" вместо IO_OPEN_FLAG_R или это был IOFLAG_R или SYSFLAGS_OPEN_RMODE или что-то еще

2
ответ дан 1 December 2019 в 10:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: