Предварительный
Вы смешиваете по крайней мере три различных понятия, которые применяются к C идентификаторам: scope , пространство имен и linkage :
Область действия - это область текста программы, в которой данная связь между идентификатором и конкретным объектом программы является видимой и может использоваться.
Пространство имен описывает тот факт, что C позволяет использовать один и тот же идентификатор в одной и той же области видимости для идентификации объектов в определенных контекстно различимых категориях: метки, теги, структура и члены объединения, и все остальное.
Связь - это то, можно ли получить доступ к переменным или функции, объявленной в одной единице перевода, из других (внешняя связь), или только из другого места в той же единице перевода (внутренняя связь) или только в пределах ее определения (без связи).
Область применения и связь по существу отдельные соображения. Объявления области видимости обычных идентификаторов могут иметь как внешнюю, так и внутреннюю связь. Декларации области видимости обычных идентификаторов могут иметь внешнюю связь или не иметь связи. Все объявления идентификаторов в другом пространстве имен не имеют связи.
Вопрос
... немного широк, но я постараюсь затронуть основные моменты.
Помимо проверки ошибок, которая требует только типов, а не идентификаторов, с какими практическими приложениями можно столкнуться при использовании области действия прототипа функции? Каковы некоторые из преимуществ этого?
Наличие области действия прототипа функции позволяет включать имена параметров в прототипы функций. Если в прототипе не предусмотрена область для идентификаторов параметров функции, то единственной областью, к которой они могут принадлежать, будет область файла, и это будет означать, что каждое имя параметра должно отличаться от любого другого в файле, и это каждой переменной области файла. Это также подразумевает, что параметры функции могут быть доступны извне функции. И, конечно же, возникнет проблема с несколькими объявлениями функций, которые предоставляют разные имена параметров. Какой беспорядок!
Это правда, что вам не нужны прототипы, которые не являются частью определений функций для предоставления имен параметров - это необязательно, в конце концов. Но позволить это большое удобство для всех. Среди преимуществ
- упрощает создание отдельных прототипов (просто возьмите один из определения функции и удалите тело функции)
- делает прототипы функций гораздо более значимыми для человек-читатель, особенно с хорошим выбором имен параметров
- , он позволяет компиляторам предоставлять более полезные диагностические c сообщения
Определение функции всегда включает возвращаемый аргумент , имя функции и аргументы функции, включая тип и имена Кажется, что наличие области действия прототипа было бы излишним, поскольку аргументы в любом случае повторно объявляются с именами
Вы, кажется, смотрите на это задом наперед. Одним из эффектов области действия прототипа функции является то, что присвоение имен параметров в прототипе не является избыточным. За исключением прототипов, которые являются частью определения функции, область действия объявлений идентификатора в прототипе функции является прототипом. Им не нужно сопоставлять один прототип данной функции с другой (хотя обычно они совпадают). Единственные имена параметров, которые имеют значение для тела функции, - это имена, связанные с определением функции.
Но по причинам, указанным ранее, среди прочего, мы обычно хотим, чтобы имена параметров появлялись в функции прототипы. Особенно в прототипах, появляющихся в заголовках или иным образом используемых в единицах перевода, отличных от тех, которые содержат определение функции.
Единственное значение, которое я вижу, это то, что оно резервирует имя функции в значении пространства имен области файла. имя функции может использоваться в прототипе
Это имеет такой эффект, хотя я редко вижу идентификатор функции, используемый в качестве имени одного из ее собственных параметров. Но более распространенным является то, что имя функции области действия файла появляется также как имя параметра какой-либо другой функции. Или, что имя переменной области файла появляется как имя параметра функции.
Я изначально думал, что область не зависит от имен, означая, что file_scope_variable_name отличается от file_scope_function_name.
Нет, это вопрос пространства имен. Имена функций и переменных принадлежат одному и тому же пространству имен (что и обычных идентификаторов), что уместно, потому что они не всегда различаются между собой контекстом.
[мой компилятор], однако, позволит объявляется как тег в пространстве имен struct / union в любой области видимости, поскольку они являются блочным элементом, таким как функция
Да, main
можно использовать в качестве тега, несмотря на то, что он также является идентификатором функция с внешней связью. А также как ярлык и как член сколь угодно многих структур и союзов. Это потому, что это отдельные пространства имен . Вместо того, чтобы пытаться выучить правило о том, как создаются пространства имен, лучше всего просто запомнить разные пространства имен - кроме всех структур и объединений, которые можно принять за категорию, их всего три.
Кроме того, main
можно использовать как имя параметра в прототипе функции или как локальную переменную функции, , поскольку такие идентификаторы имеют различную scope .
И main
можно использовать в качестве имени отдельной функции (файловой области) в любом количестве различных единиц перевода, если вам угодно, если только в TU нет более одного, а при условии, что это точно один во всей программе имеет внешнюю связь .