На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
Страницы: (3) [1] 2 3  все  ( Перейти к последнему сообщению )  
> Простой вопрос про static , найти ответ не могу в книгах
    Привет всем!
    У меня тут вопрос вроде бы простой возник : Чем отличаются статические(static) глобальные переменные от простых глобальных переменных.
      Тем же, чем статические функции (не методы класса) отличаются от просто функций - они имеют internal linkage.
      Т.е. в разных модулях могут быть переменные с одинаковым именем. Для нестатических переменных такое не прокатит.
        Если объявляешь переменную вне функции без квалификаторов, то переменная поумолчанию делается статической.

        Добавлено
        Цитата Hryak @
        Т.е. в разных модулях могут быть переменные с одинаковым именем. Для нестатических переменных такое не прокатит.

        Что-то я не сталкивался с таким. Интересно, а если в третьем модуле будет extern ссылка на переменную которая содержится одновременно в двух других модулях, то из какого модуля она залинкуется?

        Добавлено
        Я замечал только одно отличие - если объявить переменную со словом static и не использовать её, то компилятор выдаёт предупреждение "not referenced".
          ну так столкнись :) проверь - минутное дело
            Объявляя глобальную переменную статической ее нельзя будет вызвать извне данного модуля.
              Цитата GreenGen @
              Привет всем!
              У меня тут вопрос вроде бы простой возник : Чем отличаются статические(static) глобальные переменные от простых глобальных переменных.


              Статические переменные
              Статические переменные, в отличие от глобальных, неизвестны вне своей функции или файла, и сохраняют свои значения между вызовами. Это очень полезней создании обобщенных функции и библиотек функций, которые могут использовать другими программистами. Статические переменные отличаются как от локальных, так и от глобальных переменных.
              Локальные статические переменные
              Если локальная переменная объявлена с помощью спецификатора static, компилятор выделит для нее постоянное место хранения, как и для глобальной переменной Принципиальное отличие локальной статической переменной от глобальной состоит в том, что первая остается доступной лишь внутри своего блока. Проще говоря, локальная статическая переменная — это локальная переменная, сохраняющая свои значения между вызовами функции.
              Такие переменные очень полезны при создании изолированных функций, поскольку между вызовами их можно использовать в других частях программы. Если бы статических переменных не было, пришлось бы применять глобальные переменные, порождая неизбежные побочные эффекты. Примером удачного применения статических переменных является генератор чисел, который порождает новое число, используя предыдущее значение. Для хранения этого числа можно было бы использовать глобальную переменную, однако при каждом новом вызове ее пришлось бы объявлять заново, постоянно проверяя, не конфликтует ли она с другими глобальными переменными. Применение статической переменной легко решает эту проблему.
              ExpandedWrap disabled
                int series(void)
                {
                    static int series_num;
                    series_num = series_num+23;
                    return series_num;
                }

              В этом примере переменная series_num продолжает существовать между вызовами функции, а локальная переменная каждый раз создавалась бы при входе и уничтожалась при выходе из функции. Таким образом, каждый вызов функции series () порождает новый элемент ряда, используя предыдущее значение и не прибегая к глобальной переменной.
              Локальную статическую переменную можно инициализировать. Начальное значе¬ние присваивается лишь один раз, а не при каждом входе в блок, как это происходит с локальными переменными. Например, в приведенной ниже версии функции se¬ries () переменная eeries_num инициализируется числом 100.
              ExpandedWrap disabled
                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(), показан ниже.
              ExpandedWrap disabled
                /* Все функции должны находиться в одном и том же файле.  */
                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 позволяет скрывать часть программы от других модулей Это чрезвычайно важно при разработке больших и сложных программ.
              ExpandedWrap disabled
                2 GreenGen, надеюсь я заслужил +  :lol:
                Цитата polyglott @
                Если объявляешь переменную вне функции без квалификаторов, то переменная поумолчанию делается статической.

                Без каких квалификаторов? :wacko:
                А как её сделать нестатической тогда? Написать nostatic int g;, что ли? :lol:

                Цитата
                Интересно, а если в третьем модуле будет extern ссылка на переменную которая содержится одновременно в двух других модулях, то из какого модуля она залинкуется?

                Ни из какого. Линковка не пройдет.
                  Цитата Hryak @
                  А как её сделать нестатической тогда? Написать nostatic int g;, что ли?

                  Да, я ступил.

                  Цитата Hryak @
                  Без каких квалификаторов

                  Ну там всякие квалификаторы-шмалификаторы, типа const, static, auto, extern...
                    Цитата polyglott @
                    Ну там всякие квалификаторы-шмалификаторы, типа const, static, auto, extern...

                    Понятно.

                    Но квалификаторами являются только const и volatile. Остальное - спецификаторы. ;)
                      Вобщем как я понял если просто глобальная переменная то её область видимости 1 фаил в котором она объявлена а static глобальная переменная её видно во всех файлах проекта.

                      Как я понял они различаются областью видимости?
                        Цитата GreenGen @
                        Вобщем как я понял если просто глобальная переменная то её область видимости 1 фаил в котором она объявлена а static глобальная переменная её видно во всех файлах проекта.

                        Да. Тьфу ты. :wall: Нет, конечно же.
                        Пора на покой.
                        Сообщение отредактировано: Hryak -
                          Цитата GreenGen @
                          Вобщем как я понял если просто глобальная переменная то её область видимости 1 фаил в котором она объявлена а static глобальная переменная её видно во всех файлах проекта.

                          Наоборот. static глобальная переменная видна только в том файле, в котором объявлена, просто глобальная --- во всех.
                            GreenGen вообщем прочитай в книге про internal linkage (атрибут статик) и external linkage, и как проходит процесс компиляции и компоновки.
                              Цитата Hryak @
                              Написать nostatic int g;, что ли?
                              Так нельзя! Это безграмотно! Надо писать nonstatic.
                                Цитата Hryak @
                                А как её сделать нестатической тогда? Написать nostatic int g;, что ли?

                                по умолчанию функции итак имеют не статик спецификатор, а именно extern

                                Цитата Adil @
                                Так нельзя! Это безграмотно! Надо писать nonstatic.

                                тоесть грамотно ;) ,надо писать extern или ничего.
                                1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (3) [1] 2 3  все


                                Рейтинг@Mail.ru
                                [ Script execution time: 0.0746 ]   [ 15 queries used ]   [ Generated: 17.06.26, 20:31 GMT ]