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

    Расмотрим следующую программу:

    ExpandedWrap disabled
      Program SubRout;
      Var  x,y,z : real;
           k,m,n : integer;
        Procedure P1;
        Var  x,y,q : word;
             m,u : real;
           Procedure PP1;
           Var  y,t : byte;
                n : longint;
           Begin
           ..............
           End { PP1 };
        Begin
        ..............
          PP1;
        ..............
        End { P1 };
        Procedure P2;
        Var  z,v : char;
             n,r : longint;
        Begin
        ...............
        End { P2 };
      Begin
      .................
        P1;
      .................
        P2;
      .................
      End.

    Как уже было отмечено, память для переменных выделяется при старте того блока, в котором объявлены эти переменные. Следовательно, при старте основной программы память будет выделена лишь для описанных в ее разделе Var переменных x, y, z, k, m, n. Этим переменным в машинной программе будут соответствовать конкретные адреса полей памяти.

    При обращении к процедуре P1 дополнительно выделяется память для описанных в ней переменных x, y, q, m, u, а после обращения к ее внутренней процедуре PP1 - также для переменных y, t, n. Следовательно, переменная y, объявленная в основной программе, переменная y из процедуры P1 и переменная y из процедуры PP1 имеют разные адреса в памяти, т.е. на уровне Паскаль-программы они считаются разными переменными. После окончания работы процедуры PP1 память, отведенная для переменных y, t и n освобождается; после окончания работы процедуры P1 также освобождается память, занятая переменными x, y, q, m, u.

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

    В рассматриваемом примере область действия переменной x, объявленной в основной программе - вся программа, за исключением процедуры P1; переменной k - вся программа, в том числе и процедуры P1, PP1, P2; переменной q - процедура P1, в том числе и ее внутренняя процедура PP1; переменной t - только процедура PP1 и т.д.

    Переменные, объявленные в основной программе, действуют во всей этой программе. Такие переменные называют глобальными (в программе SubRout - это переменные x, y, z, k, m, n ). Переменные, объявленные в процедуре, действуют лишь в пределах этой процедуры. Это локальные переменные. Более общее определение:
    - локальными называют переменные, которые объявлены в разделах Var процедур и функций;
    - глобальными называют переменные, которые объявлены в разделах Var вне процедур и функций.
    При рассмотрении модулей пользователя будет указано, что глобальными являются не только переменные, объявленные в основной программе. Формальное отличие между локальными и глобальными переменными определяется местом их объявления: в блоках процедур и функций или вне этих блоков.

    Для размещения переменных в оперативной памяти выделяются две области, которые называются соответственно сегментом данных и сегментом стека. Все глобальные переменные размещаются в сегменте данных при старте основной программы. Следовательно, адреса этих переменных не изменяются в течение всего времени работы программы. Максимальный размер сегмента данных равен 65520 байт, его реальный размер определяется общим объемом глобальных переменных.

    Локальные переменные размещаются в сегменте стека. Память им выделяется при каждом старте соответствующей процедуры или функции. Следовательно, при повторном обращении к процедуре локальная переменная может получить адрес, не совпадающий с тем, который она имела при предыдущем обращении к этой же процедуре. Размер сегмента стека может быть задан программистом в диапазоне от 1024 до 65520 байт. По умолчанию он равен 16384 байта.

    Правила, определяющие область действия метки, несколько отличаются от правил, рассмотренных выше по отношению к области действия имен.

    Как известно, метка используется в программе только оператором Goto, который производит передачу управления к оператору, отмеченному соответствующей меткой. При этом по правилам языка Паскаль запрещается переход внутрь сложного оператора (оператор цикла, условный оператор, составной оператор и др.). Раздел операторов процедуры - это составной оператор (Begin .. End). Следовательно, переход во внутреннюю область процедуры из основной программы или из другой процедуры с помощью оператора Goto недопустим. Вход в процедуру возможен лишь с ее начала путем обращения к этой процедуре.
    С учетом вышесказанного областью действия метки является весь блок, в котором объявлена данная метка, за исключением внутренних блоков вне зависимости от наличия в них объявления меток.
    Принудительный выход из процедуры можно осуществить с помощью оператора Goto.


    Пример:
    ExpandedWrap disabled
      Procedure P3;
      Label  10;
      Var  x : real;
      Begin
        ...
        If x<0 then
          Goto 10;
        ...
        10:
      End { P3 };


    Эта же работа может быть выполнена оператором Exit, осуществляющим выход за пределы блока процедуры:

    ExpandedWrap disabled
      Procedure P3;
      Var  x : real;
      Begin
        ...
        If x<0 then
          Exit;
        ...
      End { P3 };


    Оба варианта процедуры P3 действуют совершенно одинаково, но второй вариант предпочтительнее, поскольку в нем не используется в явном виде оператор Goto. Хотя тут еще можно поспорить о стиле программирования...

    Ранее было указано на два преимущества использования процедур:
    - уменьшение текста программы и ее объема в памяти;
    - улучшение читаемости программы.

    Очень важно еще одно преимущество, определяемое тем, что выделение памяти для объявленных в процедуре переменных происходит только при ее активизации, т.е. при старте процедуры. После окончания работы процедуры память, занятая этими переменными, освобождается.
    Предположим, что в программе используются три отдельные процедуры, в каждой из которых объявлен один массив, требующий соответственно 10, 20 и 30 Кбайт памяти. Если бы эти массивы были объявлены в основной программе, то для них при старте программы было бы выделено 60 Кбайт памяти. Поскольку указанные процедуры не работают одновременно, то для массивов выделяется не более чем 30 Кбайт. Следовательно, аппарат локальных переменных в процедурах является дополнительным источником экономии памяти в программе.


    Написано по мотивам лекций Назаренко В.И.
    Сообщение отредактировано: Jin X -
      Ешё бы привести пару примеров того, где можно избежать применения меток и оператора GoTo. И, вообще, показать, что это дурной стиль программирования. Но также есть и положительные стороны этого оператора: например, выход их двух вложенных циклов "одним махом".
      0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
      0 пользователей:


      Рейтинг@Mail.ru
      [ Script execution time: 0,0602 ]   [ 15 queries used ]   [ Generated: 2.05.24, 03:38 GMT ]