Что является и не доступно для связанных файлов в C? - PullRequest
0 голосов
/ 12 апреля 2020

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

Я думаю, что если структура определена в file2.c, file1.c может использовать ее, если оба файла включают header.h, что включает в себя объявление структуры? Это не совсем имеет смысл для меня. header.h используется обоими файлами, так что я могу видеть, как они получат доступ к содержимому в нем, но я не понимаю, как они будут использовать его для доступа друг к другу.

Когда я начал программировать, я Я подумал, что это довольно просто, когда у вас есть программные файлы, они не могут получить доступ друг к другу, и эти программные файлы могут #include заголовочные файлы с определениями и объявлениями в них (например, file1.c имеет доступ к переменным / функциям / et c. определено в header.h). Оказывается, я ошибался, и все немного сложнее.

Итак, насколько я могу судить, func(), определенный в header.h, может использоваться file1.c без объявления в file1.c, если file1.c включает header.h. В отличие от var, определенного в header.h, который должен быть объявлен в file1.c с ключевым словом extern? И я думаю, что если var определено в file2.c, file1.c может использовать его, если его объявит extern, даже если ни file1.c, ни file2.c не включают header.h?

Я прошу прощения, если предыдущие абзацы не имеют смысла, у меня возникли сложности с попыткой описать то, что меня смущает. Во что бы то ни стало, отредактируйте это, если вы можете исправить ошибки или еще что-то.

Книги и веб-страницы, кажется, не помогают вообще. В конечном итоге они дают мне неправильные представления, потому что я уже чего-то не понимаю и делаю неправильные выводы, или они выдвигают концепции, которые еще больше меня отталкивают.

То, что я смотрю, что я поиск - это ответ, который все это ставит передо мной. Например, «это может получить доступ к этому при данных обстоятельствах» , «это не может получить доступ к этому» .

Ответы [ 2 ]

1 голос
/ 12 апреля 2020

Ваш вопрос спрашивает о «доступе» в нескольких точках, но я не думаю, что это то, что вы хотите использовать. Любой объект или функция могут быть доступны (для объекта: для чтения или записи, для функции: для вызова) из любой точки мира, если указатель на них каким-либо образом предоставляется). Я думаю, что вы хотите спросить, какие имена доступны.

Любое объявление, которое находится вне функции, является external объявлением. При использовании «внешнего» в стандарте C это просто означает вне функции. (Это включает в себя объявление или определение функции; хотя оно объявляет или определяет функцию, оно не находится внутри себя или какого-либо другого объявления функции, поэтому оно находится вне какой-либо функции.)

Любой идентификатор объекта или Функция с внешним объявлением имеет либо внутреннюю, либо внешнюю связь. Если он сначала объявлен с static, он имеет внутреннюю связь (и позже может быть объявлен с extern, но это не изменит связь). В противном случае он имеет внешнюю связь.

Любой идентификатор с внешней связью будет ссылаться на один и тот же объект или функцию во всех единицах перевода (при условии соблюдения других правил стандарта C - программа может выполнять различные действия, которые приведет к поведению, не определенному стандартом C.

Таким образом, ваш ответ таков: Имя любого объекта или функции, которая (а) определена вне какой-либо функции и (б) изначально не объявлена ​​с static доступен для связи с другими единицами перевода.

Некоторые технические вопросы, которые могут быть интересны:

  • То, что люди считают переменной, это две вещи: идентификатор (имя) и объект (область памяти, в которой хранится значение).
  • Идентификаторы имеют область действия, в которой они видны в исходном коде. Идентификаторы, объявленные вне функций, имеют область видимости файла; они видны для остальной части блока перевода. Идентификаторы, объявленные внутри функций, имеют различные другие типы областей действия: область действия функции, область действия прототипа функции и область действия блока.
  • Иногда может показаться, что люди ссылаются на глобальную область действия или внешнюю область действия, но это неправильные числа; они не являются терминами, используемыми в стандарте C.
  • Связь связана с областью действия и иногда путается с ней, но связь представляет собой другую концепцию: можно использовать два идентичных идентификатора, объявленных в разных местах для ссылки на тоже самое. Эти идентификаторы имеют разные области видимости, в частности, один имеет область файла в одной единице перевода, а другой - область файла в другой единице перевода. Поскольку каждая единица перевода компилируется отдельно, компилятор генерирует код для каждого идентификатора в отдельности. Когда объектные модули связаны, то код объединяется вместе, в результате чего отдельные идентификаторы ссылаются на один и тот же объект или функцию.
  • Идентификаторы могут быть объявлены с extern внутри функций, но они могут ссылаться только на объекты или функции, определенные в другом месте; внешние определения не могут появляться внутри функций.
1 голос
/ 12 апреля 2020

Функции, определенные в одном файле .c, могут использовать все, что определено в другом файле .c, за исключением тех вещей, которые помечены как static. Функции и глобальные переменные, помеченные как static, не могут быть доступны из других единиц перевода.

Независимо от того, объявлено ли что-то в заголовочном файле или нет, на самом деле не имеет значения - вы можете объявлять функции локально в одном и том же .c файл, который вызывает их, если хотите.

...