Статичний проти глобального


75

Якщо у мене є файл C, як показано нижче, в чому різниця між iі j?


1
Прочитайте відповіді на це запитання: stackoverflow.com/questions/1358400/…
avakar

Відповіді:


71

iмає внутрішнє зв’язування, тому ви не можете використовувати ім’я iв інших вихідних файлах (строго одиницях перекладу) для посилання на той самий об’єкт.

jмає зовнішню зв'язок, тому ви можете використовувати jдля посилання на цей об'єкт, якщо заявляєте про це externв іншій одиниці перекладу.


2
не повинно бути різниці у виконанні, якщо ви робите те саме, оскільки компілятор може генерувати той самий код. Хоча компіляція може бути трохи довшою з глобальним, оскільки вона має більш широкий спектр.
Флоріан Кастеллан

Чи можливо програмно визначити зв'язок будь-якої довільної змінної під час компіляції (потенційно з використанням розширення компілятора) або під час виконання? Див .: stackoverflow.com/q/65520719/9881330 .
pmor

25

iне видно за межами модуля; jдоступна у всьому світі.

Тобто інший модуль, який зв’язаний з ним, може зробити

а потім мати можливість читати та записувати значення в j. Той самий інший модуль не може отримати доступ i, але може оголосити свій власний екземпляр, навіть глобальний - який не видно першому модулю.


1
Чи потрібна декларація "extern"?
Thomas Matthews

1
Це залежить від реалізації. Використання externгарантовано не викликає проблем, якщо один модуль має символ як не- externі громадськості (що виділяє його). Ранні реалізації Unix об’єднували символи з однойменною назвою - майже як Фортран, - тому externне вимагалося.
wallyk

1
Зауважте, що "Не видно" не означає, що воно вийшло за межі поля. Це означає, що якщо ви оголосите i в іншому модулі компіляції і ви видалите статичний i з вашого .c-файлу, глобальний i буде видимим для вашого .c-файлу. На відміну від цього, якби глобальний i був поза сферою дії, це не мало би значення, якщо б у вас був оголошений статичний i у вашому файлі .c. Глобального ніколи не було б видно. static i, що має перевагу над глобальним i, визначеним в іншому блоці компіляції, називається "тінінг". Це також трапляється з функціональними місцевими жителями, і це не є лише c ++ / c.
Юпітер

6

Різниця полягає в тому, що iмає внутрішній зв’язок і jзовнішній зв’язок. Це означає, що ви можете отримати доступ jз інших файлів, на які ви посилаєтесь, тоді iяк доступний лише у файлі, де він оголошений.


4

iматиме статичну зв'язок , тобто змінна доступна лише у поточному файлі.

jслід визначати як extern, тобто

в іншому файлі заголовка ( .h), і тоді він матиме зовнішнє зв’язування , і до нього можна отримати доступ через файли.


2

Область дії статичної змінної / функції знаходиться в одному файлі, незважаючи на те, що ви включили файл як частину іншого вихідного файлу.

Сфера дії глобальної змінної знаходиться у всіх файлах, до яких вона включена. Щоб включити змінну в інший вихідний файл, ми використовуємо externперед оголошенням змінної. У цьому випадку для змінної знову не виділяється пам’ять.

externвикористовується для оголошення змінної C без її визначення. externКлючове слово розширює видимість змінних C та функцій C. Оскільки функції за замовчуванням видно через програму, використання externв декларації / визначенні функції не потрібне. Його використання зайве.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.