[SourcePawn] Урок 1 - Основы языка (Часть 2)

Тема в разделе "Программирование / Скриптинг", создана пользователем R1KO, 4 сен 2016.

  1. R1KO

    R1KO Супер-модератор

    Сообщения:
    5.995
    Симпатии:
    2.990
    [SourcePawn] Урок 1 - Основы языка (Часть 2)

    <- К содержанию

    1. <- Часть 1
    2. Функции
      Функция - фрагмент программного кода (подпрограмма), выполняющий определенные действия, к которому можно обратиться из другого места программы. После выполнения функции управление возвращается обратно в точку программы, где данная функция была вызвана.
      Прототип функции - объявление функции, не содержащее тела функции, но указывающее имя функции, типы аргументов и возвращаемый тип данных. В то время как определение функции описывает, что именно делает функция, прототип функции может восприниматься как описание её интерфейса.
      Функция состоит из
      • Типа функции
        • native: Прототип внешней функции, которая создана другими плагинами или расширениями
          PHP:
          native bool IsValidClient(int iClient);
          /*
          Сообщаем компилятору что существует внешняя функция с возвращаемым типом данных bool, которой необходимо передать 1 аргумент типа int
          */
        • public: Обратный вызов внешней функции, которая вызывает другими плагинами или расширениями
          PHP:
          public void OnMapStart()    // Внешняя функция OnMapStart вызывается ядром самого sourcemod`а
          {
              
          // код
          }
        • normal: Нормальная функция, которая может быть вызвана только внутри текущего плагина (при этом слово normal не пишется)
          PHP:
          void MyFunction()    // Внутренняя функция MyFunction
          {
              
          // код
          }
        • static: Тоже что и normal но функция доступна только в пределах текущего документа
        • stock: Тоже что и normal но если функция не вызывается нигде в плагине - компилятор не включает её в исполняемый файл (smx)
        • forward: Глобальное событие, вызываемое другими плагинами или расширениями. Является обратным вызовом и записывается только как прототип.
          PHP:
          forward void MyFunction();    // Сообщаем компилятору что существует внешняя функция MyFunction пустого типа без аргументов
      • Типа данных функции
        Аналогично типам данных переменных, но добавлен еще 1 тип:
        • void - Пустой тип. Означает что функция не возвращает никакого значения.
      • Имени функции
        К имени функции применяются те же требования что и к имени переменной
      • Параметров и аргументов функции
        Параметры функции - это значения, которые должна принимать функция.
        Аргументы функции - это те значения, которые передают в функцию при её вызове.
        PHP:
        public void OnMapStart()    // Функция без параметров
        {
            
        MyFunc(аргумент1аргумент1);    // Вызов функции, передаем аргументы
        }

        int MyFunc(параметр1параметр2)    // Объявляем функцию, принимаем параметры
        {
           
        // код
        }
        Параметры и аргументы у функции могут отсутствовать.
        PHP:
        public void OnMapStart()    // Функция без параметров
        {
            
        int a 5;
            
        int b AddNumbers(a9);    // Вызываем нашу функцию передавая её 2 аргумента
            // b сейчас равно 14
        }

        int AddNumbers(int param1int param2)    // Объявляем функцию, которая имеет 2 параметра типа int. При этом называть их можно любым удобным именем.
        {
            
        // param1 сейчас равно 5
            // param2 сейчас равно 9
            
            
        int iResult param1param2// Прибавляем наши числа и записываем это в переменную iResult
            
        return iResult;    // Возвращаем значение iResult как значение функции
        }

      Синтаксис объявления функции:
      [Тип функции] <Тип данных функции> <Имя функции> ([параметр 1], [параметр 2], ...)

      Есть 2 способа вызова функции:
      • Прямой вызов - Вы специально вызываете функцию в вашем коде.
        PHP:
        public void OnMapStart()
        {
            
        MyFunction();    // Вызываем нашу функцию
        }

        void MyFunction()    // Объявляем функцию
        {
            
        // код
        }
      • Обратный вызов - В этом случае вы передаете в функцию1 имя другой функции (функцию2) и по завершению исполнения фукнции1 будет вызваная функция2
      PHP:
      public void OnMapStart()
      {
          
      MyFunction1(MyFunction2);    // Вызываем нашу функцию MyFunction1, передавая как аргумент функцию MyFunction2
      }

      void MyFunction1(Function MyFunctionCallBack)    // Объявляем функцию MyFunction1
      {
          
      // код
          
      Call_StartFunction(nullMyFunctionCallBack);        // Вызываем нашу функцию которую передали
          
      Call_Finish();
      }

      void MyFunction2()    // Объявляем функцию MyFunction2
      {
          
      // код
      }
      Возврат (return)
      Оператор return может быть 2-х видов
      Типы данных
      • return; - Просто завершает выполнение функции и передает управление в ту часть кода, откуда функция была вызвана.
      • return значение; - Завершает выполнение функции и передает управление в ту часть кода, откуда функция была вызвана, при это возвращая значение как значение функции.
        PHP:
        public void OnMapStart()
        {
            
        int b;
            
        // b сейчас равно 0
            
        AddNumbers(32);    // Вызываем нашу функцию
            // Функция примет значение 5 и оно будет присвоено переменной b
            // b сейчас равно 14
        }

        int AddNumbers(int arg1int arg2)
        {
            
        int iResult arg1 arg2;
            return 
        iResult;    // Возвращаем значение iResult как значение функции
            /*
            Либо можно записать так:
            return (arg1 + arg2);
            */
        }
        PHP:
        public void OnMapStart()
        {
            
        int a 3;
            if(
        IsValidNumber(a))
            {
                
        // Код
            
        }
        }

        bool IsValidNumber(int iNum)
        {
            if(
        iNum && iNum 10)    // Если число, которое передали в функцию больше 0 и меньше 10
            
        {
                return 
        true;    // Вернем true
            
        }
            
        // Если условия выше выполнилось, то функция завершится и вернет true, а код ниже выполнен не будет
            
        return false;    // Вернем false
        }
      Для функций типа void return в конце функции не нужен, но может применяться return без значения для выхода из функции в нужный момент.

      Функции не могут возвращать массивы (строки тоже массивы).

      Значения по умолчанию
      В SourcePawn можно задать значение по умолчанию для любых параметров функции. Это значит, что если параметр не передан в функцию - он принимает значение по умолчанию.
      PHP:
      public void OnMapStart()
      {
          
      int a 3,
              
      6;

          
      int c MyFunc(abtrue);        // Прибавление
          
      int d MyFunc(abfalse);    // Вычитание
          
      int e MyFunc(ab);            // Прибавление
      }
      /*
      Функция MyFunc прибавляет или вычитает числа
      1-й параметр это число 1
      1-й параметр это число 2
      2-й параметр определяет действие:
          true - прибавляем
          false - вычитаем
      */
      int MyFunc(int iNum1int iNum2bool bAdd true// Если параметр bAdd не передан он будет принят как true
      {
          if(
      bAdd)    // Если bAdd равен true
          
      {
              return (
      iNum1 iNum2);    // Вернем сумму
          
      }
          else    
      // Если bAdd не равен true значит он равен false, так что проверять это нет смысла.
          
      {
              return (
      iNum1 iNum2);    // Вернем разность
          
      }

          return 
      0;
      }
      Когда пропускаемый параметр не последний заменяем его нижним подчеркиванием _
      PHP:
      public void OnMapStart()
      {
          
      int a 3,
              
      6;

          
      int c MyFunc(atrueb);        // Прибавление
          
      int d MyFunc(afalseb);    // Вычитание
          
      int e MyFunc(a_b);            // Прибавление
      }

      int MyFunc(int iNum1bool bAdd trueint iNum2// Если параметр bAdd не передан он будет принят как true
      {
          if(
      bAdd)    // Если bAdd равен true
          
      {
              return (
      iNum1 iNum2);    // Вернем сумму
          
      }
          else    
      // Если bAdd не равен true значит он равен false, так что проверять это нет смысла.
          
      {
              return (
      iNum1 iNum2);    // Вернем разность
          
      }

          return 
      0;
      }
      Передача по ссылке
      Во всех примерах представленных ранее параметры в функции передавались по значению.
      Как это работает:
      PHP:
      public void OnMapStart()
      {
          
      int a 3,
              
      6;

          
      int c AddNumbers(ab);    // Передаем значения переменных a и b
          /*
          При этом мы передаем не сами переменные, а то значение, которое в них находится.
          Это значит что мы передаем числа 3 и 6.
          */
      }

      int AddNumbers(int iNum1int iNum2// Здесь создаются новые локальные переменные и они принимают значения, которые им были переданы
      {
          
      // Здесь iNum1 это новая локальная переменная, которая равна 3, следовательно равна a но она не является переменной a.
          // Если здесь мы изменим её, например, так:
          //    iNum1 = 7;
          //    Она станет равна 7, но переменная a в функции OnMapStart по прежнему останется равна 3
          
      return (iNum1 iNum2);
      }
      Часто возникает необходимость вернуть 2 значения. Это можно сделать передав функции параметры не по значению, а по ссылке.
      PHP:
      public void OnMapStart()
      {
          
      int a 3,
              
      6;

          
      int c;
          
      //     c == 0
          
      AddNumbers(abc);    // Передаем значения переменных a и b и адрес переменной с
          //     c == 9
      }

      void AddNumbers(int iNum1int iNum2int &iResult// & означает, что функция получает не значение переменной, а её адрес
      {
          
      // Здесь переменная iResult это та же переменная что и c в функции OnMapStart;
          // Если мы её изменим здесь, то изменится и переменная c
          
      iResult iNum1 iNum2;
      }
      Массивы всегда передаются по ссылке, но символ & не ставится.
      PHP:
      public void OnMapStart()
      {
          
      int iArray[4] = {4581};

          
      MyFunc(iArray4);
          
      MyFunc2(iArray);
      }

      void MyFunc(int[] iArrayint iSize)    // Такая запись используется, если функция не знает точного размера массива, поэтому часто её нужно передать еще и размер массива
      {
          
      // Код
      }

      void MyFunc2(int iArray[4])    // Такая запись используется, если функция всегда должна принимать массив указанного размера
      {
          
      // Код
      }
    3. Методы
      Метод - это функция, принадлежащая какому-то классу или объекту.
      Например, в SourcePawn есть стандартный класс Panel, который является дочерним от Handle.
      Класс Panel имеет специальные функции для работы с ним.
      Несколько их них:
      • Panel - Конструктор класса, создает объект класса Panel (Создает панель)
      • SetTitle - Добавляет заглавие в панель
      • DrawItem - Добавляет пункт в панель
      • DrawText - Добавляет текст в панель
      • Send - Отправляет панель игроку.
      Эти функции и есть его методами.
      Более подробно о конкретных классах и их методах будет изложено в следующих уроках.

    4. Константы
      Константы - переменные, которые нельзя изменить после инициализации.
      Константы бывают:
      • Литеральные - Значение, записанное непосредственно в коде
        PHP:
        public void OnMapStart()
        {
            
        int a 3;

            
        int c AddNumbers(a4);    // 4 это литеральная константа
        }

        int AddNumbers(int iNum1int iNum2)
        {
            return (
        iNum1 iNum2);
        }
        • Именованные - Присвоение имени значению и последующая замена при компиляции
          PHP:

          #define NUMBER    4

          public void OnMapStart()
          {
              
          int a 3;

              
          int b NUMBER;    // NUMBER будет заменено на 4
          }
        • Перечисления - Для использования целочисленных констант можно использовать перечисления, в котором целочисленному значению сопоставляется определенное имя. По умолчанию первой константе задается значение 0, а другим значение на 1 большее, чем предыдущая константа.
          PHP:
          enum
          {
              
          NONE = -1,    // Первое значение -1
              
          SELF,        // == 0
              
          TEAM,        // == 1
              
          ALL,        // == 2
          };

          public 
          void OnMapStart()
          {
              
          int iMode TEAM;    // Значение равно 1
          }
        • Константы переменных - Это тип переменных, значение которым присваивается на этапе инициализации и его больше нельзя изменить.
          PHP:
          static const int g_iGlobalVar 7;    // Переменная g_iGlobalVar всегда будет равно 7 и её нельзя изменить
          // static нужен при создании глобальных констант т.к. этого требует синтаксис

          public void OnMapStart()
          {
              const 
          int iLocalVar 9;    // Переменная iLocalVar всегда будет равно 9 и её нельзя изменить
          }
          PHP:
          public void OnMapStart()
          {
              
          char sVar[] = "string";
              
          MyFunc(sVar);
          }

          void MyFunc(const char[] sString)    // Функция не знает, какой реальный размер переданной строки, но переменную нельзя изменить
          {
              
          // Код
          }

          void MyFunc2(int iArray[4])    // Такая запись используется, если функция всегда должна принимать массив указанного размера
          {
              
          // Код
          }

      • Циклы
        Циклы - инструменты, которые позволяют многоразово выполнять блок кода.
        Цикл состоит из условия выполнения и тела цикла.
        Итерация - единичное выполнение тела цикла.
        • Цикл for - Используется, когда известно точное количество итераций
          PHP:
          for (действие до начала циклаусловие продолжения цикладействия в конце каждой итерации цикла)
          {
              
          // Тело цикла
          }
          Частный случай:
          PHP:
          for (счетчик значениесчетчик значениешаг цикла)
          {
              
          // Тело цикла
          }
          PHP:
          for (int i 05i++)    // Будет выполнятся до тех пор, пока i меньше 5
          {
              
          PrintToServer("i = %i;"i);
          }
          /*
          int i = 0; - Здесь мы создали счетчик (переменная, которая ведет подсчет итераций)
          i < 5; - Это условие, которое проверяет перед каждой итерацией (Условие продолжения)
          i++ - Это действие, которое выполняется после каждой итерации
          */
          Результат выполнения:
        • Цикл while - Когда мы не знаем, сколько итераций должен произвести цикл. Данный цикл будет выполняться, пока условие, является истиной.
          PHP:
          while (условие продолжения цикла)
          {
              
          // Тело цикла
          }
          PHP:
          int i 5;
          while (
          0)
          {
              
          PrintToServer("i = %i;"i);
              
          i--;
          }
          Результат выполнения:
        • Цикл do while - То же что и while, но проверка условия выполняется уже после выполнения итерации. Это гарантирует хотя бы одно выполнение цикла.
          PHP:
          do
          {
              
          // Тело цикла
          } while (условие продолжения цикла)
          PHP:
          int i 5;
          do
          {
              
          // Тело цикла
              
          PrintToServer("i = %i;"i);
              
          i--;
          } while (
          0)
        Операторы для работы с циклами
        • break; - Прекращает выполнение цикла и возвращает управление в функцию.
        • return [значение]; - Прекращает выполнение цикла и выходит из функции.
        • continue; - Пропускает выполнение текущей итерации цикла.
      • Ключевые слова
        Ключевые слова - это слова, которые зарезервированы самим SourcePawn и их нельзя использовать, как имена переменных и фукнций.
        К ним относятся if, for, return и другие.
        Если вы попытаетесь использовать ключевые слова как имена переменных и функций то получите ошибку:
      • Инструкции компилятора
        Инструкции компилятора - это инструкции, которые нужны для компилятора. После компиляции их нет в исполняемом файле.
        Инструкции компилятора всегда начинаются с символа #
        • #include - Подключает указанный файл/библиотеку
          Использование:
          • #include <sourcemod> - Подключает библиотеку sourcemod из папки include, относительно расположения компилятора
          • #include "myfile.sp" - Подключает файл myfile.sp по пути относительно текущего файла
        • #tryinclude - То же что и #include но если файла не существует то ошибки не будет.
        • #define имя_макроса последовательность_символов - Создает макрос. В результате, если компилятор обнаружит в тексте программы имя_макроса, то он заменит его на последовательность_символов.
          Макрос заканчивается переносом строки. Для экранирования переносов строк в макросе используется символ \
        • #if условие - Выполняет проверку условия. Требуется закрывающая директива #endif. Возможно ветвление используя директивы #else и #elseif
        • #if defined имя_макроса - Проверяет объявлен ли макрос.
        • #error "Ошибка" - Выдает ошибку компиляции.
        • #pragma - Директива используется для доступа к специфическим расширениям компилятора.
          Использование:
          • #pragma semicolon 1 - Сообщает компилятору о том, что в конце каждого выражения должен стоять символ ;
          • #pragma newdecls required - Сообщает компилятору о том, что синтаксис плагина исключительно новый
          • #pragma deprecated - Устанавливает для переменной/функции статус устаревшей
          • #pragma dynamic количество_байт - Устанавливает динамичную память плагина
          • #pragma unused - Отключает предупреждение о то что переменная не используется
          • #pragma tabsize размер - Устанавливает значение TAB (0 - отключает)
    5. <- Часть 1
    Жду критики, пожеланий, предложений, отзывов.
     
    Последнее редактирование: 21 ноя 2016
    T1MOXA, Altaj, Someone и 2 другим нравится это.
  2. gibs

    gibs Фитиль народного волненья

    Сообщения:
    540
    Симпатии:
    137
    Ну ты путаешь понятия препроцессорных деректив и встроенных функций. sizeof() - это встроенная функция.
    На счёт процедур я бы не согласился. Тут стоит делать отсылку к си. В языке нету понятия процедуры, тут всё является функциями.
    По поводу методов. Это переопредение стандартных типов. Классов и структур в павне как таковых нету. Можно создавать структуру через enum, описывать последовательность типов и объявлять массив, но это не совсем структура, да и какой это нафиг класс, который может хранить лишь одно единственное свойство.
    С приходом методмапов язык остается как и раньше процедурным. В нормальном ООП языке был бы просто класс, который наследуется от интерфейсов, в методах которого описывались бы действия, что и являлось бы плагином. В пример могу привести написание С++ плагинов. Тут же методмапы были введены не в качестве стремления к ООП, а скорее ради возможности сокращать записи.
    Для новичков и школьников я дам просто совет: если вы решили заняться программированием, то поверьте, сорспавн - это язык, с которого точно не стоит начинать этого делать. Он не является самостоятельным языком.
     
  3. R1KO

    R1KO Супер-модератор

    Сообщения:
    5.995
    Симпатии:
    2.990
    исправил.
    Соглашусь, и так ясно что методмап это не класс, я "обозвал" их классами новичкам было проще ориентироваться.
     
  4. AlmazON

    AlmazON деревянный © yand3xmail

    Сообщения:
    4.553
    Симпатии:
    1.987
    Опечатка.
    Лишнее.
    Если верить тому же декомпилятору, то он всегда преобразуется в простой while. Разве не так? Или, всё же есть разница и, в качестве оптимизации действительно всегда стоит использовать for, когда число итераций заведомо известно?
     
  5. R1KO

    R1KO Супер-модератор

    Сообщения:
    5.995
    Симпатии:
    2.990
    @AlmazON, судя по всему он действительно преобразуется, но for удобен в использовании, да и какая разница если после компиляции всё ровно получим одно и то же, лучше же делать удобно.
    Остальное исправил
     
  6. gibs

    gibs Фитиль народного волненья

    Сообщения:
    540
    Симпатии:
    137
    Я тебе уже говорил, что у тебя довольно искривлённое понятие оптимизации. Цикл фор - это попросту удобный оператор цикла, который призван делать написание кода более компактно и читаемо за счёт своей удобной структуры, и который входит в структуру языка. Если ты задаешь вопрос какой цикл использовать для оптимизации, то это полный п*здец, извините за выражение.
     
  7. AlmazON

    AlmazON деревянный © yand3xmail

    Сообщения:
    4.553
    Симпатии:
    1.987
    Тогда ещё назло спрошу: что оптимальнее использовать, цикл while или do while, если содержимое одно и то же, по сути (первое выполнение возможно без проверок)? :mosking:
    Замечу, что нигде не сказано об этом, будто они действительно обособлены друг от друга, а выполняют ту же функцию. Думаю, это полезно будет знать всем.
     
  8. gibs

    gibs Фитиль народного волненья

    Сообщения:
    540
    Симпатии:
    137
    @AlmazON, это зависит от компилятора и уровня оптимизации компилятором. Если брать сорсмод, то исходный код транслируется в байт код, потом через jit в машинный код. Все опткоды для jit можно посмотреть тут, но основная документация тут. На деле циклы вайл и фор практически идентичны, отличаются лишь удобностью записи. В байт коде это по прежнему проверка условия и джампы по адресам. Первое и третье поле в цикле фор является не обязательным, обязательно указывать только проверка условий, так что можно использовать фор в качестве вайла, при этом байт код будет одинаковый. Но в цикле вайл нельзя создавать переменные, которые будут видимы только для тела цикла.
    А вот пример.
    PHP:
    public Action Cmd_Test(int args)
    {
        for (
    int i 003i++)
        {
            
    2;
        }
      
        
    int i 00;
        while(
    3)
        {
            
    2;
            
    i++;
        }
      
        return 
    Plugin_Handled;
    }
    PHP:
    0xba0: break                          
    0xba4: break                          
    0xba8push.c 0x0                       0
    0xbb0
    push.c 0x0                       0
    0xbb8
    jump 0xbcc                       ; +0x14
    0xbc0
    : break                          
    0xbc4inc.s 0xfffffffc                 i
    0xbcc
    load.s.pri 0xfffffffc            i
    0xbd4
    : const.alt 0x3                    3
    0xbdc
    jsgeq 0xc08                      ; +0x2c
    0xbe4
    : break                          
    0xbe8load.s.pri 0xfffffff8            j
    0xbf0
    add.c 0x2                        2
    0xbf8
    stor.s.pri 0xfffffff8            j
    0xc00
    jump 0xbc0                       ; -0x40
    0xc08
    stack 0x8                        8
    0xc10
    : break                          
    0xc14push.c 0x0                       0
    0xc1c
    push.c 0x0                       0
    0xc24
    : break                          
    0xc28: break                          
    0xc2cload.s.pri 0xfffffffc            i
    0xc34
    : const.alt 0x3                    3
    0xc3c
    jsgeq 0xc74                      ; +0x38
    0xc44
    : break                          
    0xc48load.s.pri 0xfffffff8            j
    0xc50
    add.c 0x2                        2
    0xc58
    stor.s.pri 0xfffffff8            j
    0xc60
    : break                          
    0xc64inc.s 0xfffffffc                 i
    0xc6c
    jump 0xc28                       ; -0x44
    0xc74
    : break                          
    0xc78: const.pri 0x3                    3
    0xc80
    stack 0x8                        8
    0xc88
    retn                            
    В обоих случаях один и тот же сценарий
    Код:
    0xc2c: load.s.pri 0xfffffffc            ; i
    0xc34: const.alt 0x3                    ; 3
    0xc3c: jsgeq 0xc74                      ; +0x38
    
    Подгружается два значения, и если не совпадают условия, то прыжок по адресу.
    ЗЫ: и нету никакого там превращения из фора в вайл. Просто декомпилятор так интерпретирует опткоды
     
    san911 нравится это.
  9. DarklSide

    DarklSide

    Сообщения:
    684
    Симпатии:
    173
    2. Функции


    P.S.:

    <<Возврат (return)
    <<return значение; - Завершает выполнение функции и передает управление в ту часть кода, откуда функция была вызвана, при это возвращая значение как значение функции.

    [Add+] При возращении "return (значение или выражение" - объявляется неявно (временная) переменная, и она присваивается к той переменной(iResult), которая вызвала эту функцию 'AddNumbers(5, 9)'.

    int iResult = AddNumbers(5, 9);

    Объявляется неявно (временная) переменная - её время заканчивается: после успешного присвоения к переменной (iResult).


    Параметры функций

    <<Параметры функции - это значения, которые должна принимать функция.
    <<Аргументы функции - это те значения, которые передают в функцию при её вызове.

    [Fix*] Параметры функции -> Формальные параметры - аргументы, при объявлении функции.

    PHP:
    int AddNumbers(int param1int param2// Определяем функцию, которая имеет формальные параметры - 2 аргумента типа int: param1(a), param2(9).
    {
       
    // тело функции.
    }
    [Fix*] Аргументы функции -> Фактические параметры - аргументы, передаваемые в функцию,
    (аргумент может быть выражение).

    PHP:
    int a 5;
    int b AddNumbers(a9); // Вызываем нашу функцию, передавая фактические параметры - 2 аргумента типа int: a(param1) и 9(param2).

    [Add+] Если формальные параметры (их аргументы, при объявлении функции) - не передаются явно по ссылке (оператор &), или он не является массивом,-
    т.е. передаются по значению (по умолчанию), и неявно присваивает фактический параметр, значения формального.

    Образно (без констант):
    - По значению:
    Фактический параметр (аргумент, его значение копируется в)-> Формальный параметр. При этом неявно объявляется локальная переменная, именем равным формального параметра.

    - По ссылке:
    Фактический параметр (аргумент, его &адрес передается в)-> Формальный параметр. Не объявляется локальная переменная, но и доступна изменению по имени формального параметра.

    - Массив:
    Фактический параметр ((аргумент, (неявный &) его адрес-на первый элемент массива) передается в)-> Формальный параметр. Не объявляется локальная переменная, но и доступна изменению по имени формального параметра.


    Если нужно передать только переменную - без её изменения в функции, то можно использовать передачу по ссылке со спецификатором const от случайного изменения.
    PHP:
    public void OnPluginStart()
    {
       
    int iRes5 5;
       
    int iRes10 10;
       
    int iResult AddNumbers(iRes5iRes10);
       
    PrintToServer("Text_OnPluginStart - iResult = %d"iResult); // Text_OnPluginStart - iResult = 15

       
    int iEq iResult;

       
    // Если переменная iRes5 больше не требуется, можно присвоить ей новое значение
       // главное не запутаться в именах, и/или присвоить ей имя под двойное значение,
       // например iRes5_iEq, чтобы не объявлять, как выше iEq ->
       // -> iRes5_iEq = iResult
       
    iRes5 iResult;

       
    PrintToServer("Text_OnPluginStart - iEq = %d, iRes5 = %d"iEqiResult); // Text_OnPluginStart - iEq = 15, iRes5 = 15


       // Аналог (аргумент как выражение):
       
    PrintNoCreateiResult(); // Простой вызов функции без фактических параметров
    }

    void PrintNoCreateiResult() // Без формальных параметров, iRes5 и iRes10 не передаются
    {
       
    // объявляем новые локальные переменные для этой функции,
       // т.к. по области видимости с прежней функцией они - неизвестны.
       
    int iRes8 8;
       
    int iRes13 13;

       
    // Аргумент может быть выражение, т.к. при возращении (return) объявляется неявное (временная) переменная.
       // Поэтому нет нужды объявлять iResult, если не потребуется дальше в функции,
       // собственно замысел - аргумент как выражение.
       
    PrintToServer("Text_PrintNoCreateiResult - AddNumbers(iRes8, iRes13) = %d"AddNumbers(iRes8iRes13)); // Text_PrintNoCreateiResult - AddNumbers(iRes8, iRes13) = 21

       //дальше iResult не требуется.

       //P.S.: т.к. AddNumbers(iRes5, iRes10) не конец выражения (в данный момент), поэтому после - символ ";" не ставиться.
    }

    int AddNumbers(const int &param1, const int &param2// Определяем функцию, которая имеет формальные параметры - 2 аргумента типа int переданный их адрес: &param1(iRes5), &param2(iRes10).
    {
       
    // При этом имеем в формальных параметрах (только переданный адрес), без неявного объявления локальных переменных.
       
    PrintToServer("Text_AddNumbers - param1 = %d, param2 = %d"param1param2); // Text_AddNumbers - param1 = 5, param2 = 10
       
    return param1 param2;
    }

    Text_AddNumbers - param1 = 5, param2 = 10
    Text_OnPluginStart - iResult = 15
    Text_OnPluginStart - iEq = 15, iRes5 = 15
    Text_PrintNoCreateiResult - AddNumbers(iRes8, iRes13) = 21
     
    Последнее редактирование: 7 сен 2016
  10. R1KO

    R1KO Супер-модератор

    Сообщения:
    5.995
    Симпатии:
    2.990
    @DarklSide, мне кажется формальные и фактические только запутают, да и учить это лучше на других языках.
     
  11. inklesspen

    inklesspen После "Р" в слове "Лопата"

    Сообщения:
    836
    Симпатии:
    198
    Слишком много муккулатуры, долго читать...
    Надо бы какой-нить краткий урок) Ото приходят со школы и лень уже (Живой пример - Я), и будут богаты таким знанием лишь те, кто уже отучились.
     
  12. gibs

    gibs Фитиль народного волненья

    Сообщения:
    540
    Симпатии:
    137
    @inklesspen, иногда просто удивительно какую же люди порой чушь умудряются морозить.
     
    T1MOXA нравится это.