Простой вопрос про static
, найти ответ не могу в книгах
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.216.189] |
|
|
| Страницы: (3) [1] 2 3 все ( Перейти к последнему сообщению ) |
Простой вопрос про static
, найти ответ не могу в книгах
|
Сообщ.
#1
,
|
|
|
|
Привет всем!
У меня тут вопрос вроде бы простой возник : Чем отличаются статические(static) глобальные переменные от простых глобальных переменных. |
|
Сообщ.
#2
,
|
|
|
|
Тем же, чем статические функции (не методы класса) отличаются от просто функций - они имеют internal linkage.
Т.е. в разных модулях могут быть переменные с одинаковым именем. Для нестатических переменных такое не прокатит. |
|
Сообщ.
#3
,
|
|
|
|
Если объявляешь переменную вне функции без квалификаторов, то переменная поумолчанию делается статической.
Добавлено Цитата Hryak @ Т.е. в разных модулях могут быть переменные с одинаковым именем. Для нестатических переменных такое не прокатит. Что-то я не сталкивался с таким. Интересно, а если в третьем модуле будет extern ссылка на переменную которая содержится одновременно в двух других модулях, то из какого модуля она залинкуется? Добавлено Я замечал только одно отличие - если объявить переменную со словом static и не использовать её, то компилятор выдаёт предупреждение "not referenced". |
|
Сообщ.
#4
,
|
|
|
|
ну так столкнись
проверь - минутное дело |
|
Сообщ.
#5
,
|
|
|
|
Объявляя глобальную переменную статической ее нельзя будет вызвать извне данного модуля.
|
|
Сообщ.
#6
,
|
|
|
|
Цитата GreenGen @ Привет всем! У меня тут вопрос вроде бы простой возник : Чем отличаются статические(static) глобальные переменные от простых глобальных переменных. Статические переменные Статические переменные, в отличие от глобальных, неизвестны вне своей функции или файла, и сохраняют свои значения между вызовами. Это очень полезней создании обобщенных функции и библиотек функций, которые могут использовать другими программистами. Статические переменные отличаются как от локальных, так и от глобальных переменных. Локальные статические переменные Если локальная переменная объявлена с помощью спецификатора static, компилятор выделит для нее постоянное место хранения, как и для глобальной переменной Принципиальное отличие локальной статической переменной от глобальной состоит в том, что первая остается доступной лишь внутри своего блока. Проще говоря, локальная статическая переменная — это локальная переменная, сохраняющая свои значения между вызовами функции. Такие переменные очень полезны при создании изолированных функций, поскольку между вызовами их можно использовать в других частях программы. Если бы статических переменных не было, пришлось бы применять глобальные переменные, порождая неизбежные побочные эффекты. Примером удачного применения статических переменных является генератор чисел, который порождает новое число, используя предыдущее значение. Для хранения этого числа можно было бы использовать глобальную переменную, однако при каждом новом вызове ее пришлось бы объявлять заново, постоянно проверяя, не конфликтует ли она с другими глобальными переменными. Применение статической переменной легко решает эту проблему. ![]() ![]() int series(void) { static int series_num; series_num = series_num+23; return series_num; } В этом примере переменная series_num продолжает существовать между вызовами функции, а локальная переменная каждый раз создавалась бы при входе и уничтожалась при выходе из функции. Таким образом, каждый вызов функции series () порождает новый элемент ряда, используя предыдущее значение и не прибегая к глобальной переменной. Локальную статическую переменную можно инициализировать. Начальное значе¬ние присваивается лишь один раз, а не при каждом входе в блок, как это происходит с локальными переменными. Например, в приведенной ниже версии функции se¬ries () переменная eeries_num инициализируется числом 100. ![]() ![]() int series(void) { static int series_nuiti = 100; series_num = series_num+23; return series_num; } Теперь ряд будет всегда начинаться с числа 123. Хотя во многих приложениях это вполне приемлемо, обычно генераторы чисел предоставляют пользователю право выбора начального значения. Для этого можно сделать переменную series_num глобальной. Однако именно для того, чтобы избежать этого, и были созданы статические переменные. Это приводит ко второму способу использования статических переменных. Глобальные статические переменные Применение спецификатора static к глобальной переменной заставляет компилятор создать глобальную переменную, видимую только в пределах текущего файла. Несмотря на то что эта переменная остается глобальной, в других файлах она не существует. Следовательно, изменить ее значение путем вмешательства извне невозможно. Это предотвращает побочные эффекты. В некоторых ситуациях, в которых локальные статические переменные оказываются недостаточными, можно создать небольшой файл, содержащий лишь функции, которые используют конкретную глобальную статическую переменную, отдельно скомпилировать его и применять без риска возникновения побочных эффектов. Чтобы проиллюстрировать применение глобальной статической переменной, перепишем генератор чисел из предыдущего раздела таким образом, чтобы начальное значение задавалось при вызове функции series_start(). Весь файл, содержащий функции eeriest), series_start () и series_num(), показан ниже. ![]() ![]() /* Все функции должны находиться в одном и том же файле. */ static int series_num; void series_start(int seed); int series(void); int series(void) { series_num = series_num+23 ; return series_num; } /* Инициализация переменной series_num */ void series_start(int seed) { series_num = seed; } Вызов функции series_start() инициализирует генератор чисел. После этого следующий элемент ряда порождается новым вызовом функции seriesO. К сведению: локальные статические переменные видимы лишь в пределах блока, где они объявлены, а глобальные статические переменные — в пределах файла. Если поместить функции series() и series() и start() в библиотеку, то переменная series_num станет невидимой. Более того, в программе можно объявить новую переменную series_num (разумеется, в другом файле). По существу модификатор static позволяет создавать переменные, видимые лишь в пределах функций не порождая побочных эффектов. Модификатор static позволяет скрывать часть программы от других модулей Это чрезвычайно важно при разработке больших и сложных программ. ![]() ![]() 2 GreenGen, надеюсь я заслужил + :lol: |
|
Сообщ.
#7
,
|
|
|
|
Цитата polyglott @ Если объявляешь переменную вне функции без квалификаторов, то переменная поумолчанию делается статической. Без каких квалификаторов? А как её сделать нестатической тогда? Написать nostatic int g;, что ли? Цитата Интересно, а если в третьем модуле будет extern ссылка на переменную которая содержится одновременно в двух других модулях, то из какого модуля она залинкуется? Ни из какого. Линковка не пройдет. |
|
Сообщ.
#8
,
|
|
|
|
Цитата Hryak @ А как её сделать нестатической тогда? Написать nostatic int g;, что ли? Да, я ступил. Цитата Hryak @ Без каких квалификаторов Ну там всякие квалификаторы-шмалификаторы, типа const, static, auto, extern... |
|
Сообщ.
#9
,
|
|
|
|
Цитата polyglott @ Ну там всякие квалификаторы-шмалификаторы, типа const, static, auto, extern... Понятно. Но квалификаторами являются только const и volatile. Остальное - спецификаторы. |
|
Сообщ.
#10
,
|
|
|
|
Вобщем как я понял если просто глобальная переменная то её область видимости 1 фаил в котором она объявлена а static глобальная переменная её видно во всех файлах проекта.
Как я понял они различаются областью видимости? |
|
Сообщ.
#11
,
|
|
|
|
Цитата GreenGen @ Вобщем как я понял если просто глобальная переменная то её область видимости 1 фаил в котором она объявлена а static глобальная переменная её видно во всех файлах проекта. Нет, конечно же.Пора на покой. |
|
Сообщ.
#12
,
|
|
|
|
Цитата GreenGen @ Вобщем как я понял если просто глобальная переменная то её область видимости 1 фаил в котором она объявлена а static глобальная переменная её видно во всех файлах проекта. Наоборот. static глобальная переменная видна только в том файле, в котором объявлена, просто глобальная --- во всех. |
|
Сообщ.
#13
,
|
|
|
|
GreenGen вообщем прочитай в книге про internal linkage (атрибут статик) и external linkage, и как проходит процесс компиляции и компоновки.
|
|
Сообщ.
#14
,
|
|
|
|
Цитата Hryak @ Так нельзя! Это безграмотно! Надо писать nonstatic. Написать nostatic int g;, что ли? |
|
Сообщ.
#15
,
|
|
|
|
Цитата Hryak @ А как её сделать нестатической тогда? Написать nostatic int g;, что ли? по умолчанию функции итак имеют не статик спецификатор, а именно extern Цитата Adil @ Так нельзя! Это безграмотно! Надо писать nonstatic. тоесть грамотно ,надо писать extern или ничего. |