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

Pushistik↯❤

Команда форума
Регистрация
6 Июл 2017
Сообщения
393
Реакции
97
Баллы
28
[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(a, 9);    // Вызываем нашу функцию передавая её 2 аргумента
          // b сейчас равно 14
      }
      
      int AddNumbers(int param1, int param2)    // Объявляем функцию, которая имеет 2 параметра типа int. При этом называть их можно любым удобным именем.
      {
          // param1 сейчас равно 5
          // param2 сейчас равно 9
          
          int iResult = param1+ param2; // Прибавляем наши числа и записываем это в переменную 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(null, MyFunctionCallBack);        // Вызываем нашу функцию которую передали
            Call_Finish();
        }
        
        void MyFunction2()    // Объявляем функцию MyFunction2
        {
            // код
        }
        Возврат (return)
        Оператор return может быть 2-х видов
        Типы данных
        • return; - Просто завершает выполнение функции и передает управление в ту часть кода, откуда функция была вызвана.
        • return значение; - Завершает выполнение функции и передает управление в ту часть кода, откуда функция была вызвана, при этом возвращая значение как значение функции.
        PHP:
        public void OnMapStart()
        {
            int b;
            // b сейчас равно 0
            b = AddNumbers(3, 2);    // Вызываем нашу функцию
            // Функция примет значение 5 и оно будет присвоено переменной b
            // b сейчас равно 5
        }
        
        int AddNumbers(int arg1, int 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 > 0 && iNum < 10)    // Если число, которое передали в функцию больше 0 и меньше 10
            {
                return true;    // Вернем true
            }
            // Если условия выше выполнилось, то функция завершится и вернет true, а код ниже выполнен не будет
            return false;    // Вернем false
        }
        Для функций типа void return в конце функции не нужен, но может применяться return без значения для выхода из функции в нужный момент.

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

        Значения по умолчанию
        В SourcePawn можно задать значение по умолчанию для любых параметров функции. Это значит, что если параметр не передан в функцию - он принимает значение по умолчанию.
        PHP:
        public void OnMapStart()
        {
            int a = 3,
                b = 6;
        
            int c = MyFunc(a, b, true);        // Прибавление
            int d = MyFunc(a, b, false);    // Вычитание
            int e = MyFunc(a, b);            // Прибавление
        }
        /*
        Функция MyFunc прибавляет или вычитает числа
        1-й параметр это число 1
        1-й параметр это число 2
        2-й параметр определяет действие:
            true - прибавляем
            false - вычитаем
        */
        int MyFunc(int iNum1, int iNum2, bool 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,
                b = 6;
        
            int c = MyFunc(a, true, b);        // Прибавление
            int d = MyFunc(a, false, b);    // Вычитание
            int e = MyFunc(a, _, b);            // Прибавление
        }
        
        int MyFunc(int iNum1, bool bAdd = true, int 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,
                b = 6;
        
            int c = AddNumbers(a, b);    // Передаем значения переменных a и b
            /*
            При этом мы передаем не сами переменные, а то значение, которое в них находится.
            Это значит что мы передаем числа 3 и 6.
            */
        }
        
        int AddNumbers(int iNum1, int iNum2) // Здесь создаются новые локальные переменные и они принимают значения, которые им были переданы
        {
            // Здесь iNum1 это новая локальная переменная, которая равна 3, следовательно равна a но она не является переменной a.
            // Если здесь мы изменим её, например, так:
            //    iNum1 = 7;
            //    Она станет равна 7, но переменная a в функции OnMapStart по прежнему останется равна 3
            return (iNum1 + iNum2);
        }
        Часто возникает необходимость вернуть 2 значения. Это можно сделать передав функции параметры не по значению, а по ссылке.
        PHP:
        public void OnMapStart()
        {
            int a = 3,
                b = 6;
        
            int c;
            //     c == 0
            AddNumbers(a, b, c);    // Передаем значения переменных a и b и адрес переменной с
            //     c == 9
        }
        
        void AddNumbers(int iNum1, int iNum2, int &iResult) // & означает, что функция получает не значение переменной, а её адрес
        {
            // Здесь переменная iResult это та же переменная что и c в функции OnMapStart;
            // Если мы её изменим здесь, то изменится и переменная c
            iResult = iNum1 + iNum2;
        }
        Массивы всегда передаются по ссылке, но символ & не ставится.
        PHP:
        public void OnMapStart()
        {
            int iArray[4] = {4, 5, 8, 1};
        
            MyFunc(iArray, 4);
            MyFunc2(iArray);
        }
        
        void MyFunc(int[] iArray, int iSize)    // Такая запись используется, если функция не знает точного размера массива, поэтому часто её нужно передать еще и размер массива
        {
            // Код
        }
        
        void MyFunc2(int iArray[4])    // Такая запись используется, если функция всегда должна принимать массив указанного размера
        {
            // Код
        }
    • Методы
      Метод - это функция, принадлежащая какому-то классу или объекту.
      Например, в SourcePawn есть стандартный класс Panel, который является дочерним от Handle.
      Класс Panel имеет специальные функции для работы с ним.
      Несколько их них:
      • Panel - Конструктор класса, создает объект класса Panel (Создает панель)
      • SetTitle - Добавляет заглавие в панель
      • DrawItem - Добавляет пункт в панель
      • DrawText - Добавляет текст в панель
      • Send - Отправляет панель игроку.
      Эти функции и есть его методами.
      Более подробно о конкретных классах и их методах будет изложено в следующих уроках.
    • Константы
      Константы - переменные, которые нельзя изменить после инициализации.
      Константы бывают:
      • Литеральные - Значение, записанное непосредственно в коде
        PHP:
        public void OnMapStart()
        {
            int a = 3;
        
            int c = AddNumbers(a, 4);    // 4 это литеральная константа
        }
        
        int AddNumbers(int iNum1, int iNum2)
        {
            return (iNum1 + iNum2);
        }
      • Именованные - Присвоение имени значению и последующая замена при компиляции
        PHP:
        #define NUMBER    4
        
        public void OnMapStart()
        {
            int a = 3;
        
            int b = a + 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 = 0; i < 5; i++)    // Будет выполнятся до тех пор, пока i меньше 5
        {
            PrintToServer("i = %i;", i);
        }
        /*
        int i = 0; - Здесь мы создали счетчик (переменная, которая ведет подсчет итераций)
        i < 5; - Это условие, которое проверяет перед каждой итерацией (Условие продолжения)
        i++ - Это действие, которое выполняется после каждой итерации
        */
        Результат выполнения:
        i = 0;
        i = 1;
        i = 2;
        i = 3;
        i = 4;
      • Цикл while - Когда мы не знаем, сколько итераций должен произвести цикл. Данный цикл будет выполняться, пока условие, является истиной.
        PHP:
        while (условие продолжения цикла)
        {
            // Тело цикла
        }
        PHP:
        int i = 5;
        while (i > 0)
        {
            PrintToServer("i = %i;", i);
            i--;
        }
        Результат выполнения:
        i = 5;
        i = 4;
        i = 3;
        i = 2;
        i = 1;
      • Цикл do while - То же что и while, но проверка условия выполняется уже после выполнения итерации. Это гарантирует хотя бы одно выполнение цикла.
        PHP:
        do
        {
            // Тело цикла
        } while (условие продолжения цикла)
        PHP:
        int i = 5;
        do
        {
            // Тело цикла
            PrintToServer("i = %i;", i);
            i--;
        } while (i > 0)
        Операторы для работы с циклами
        • break; - Прекращает выполнение цикла и возвращает управление в функцию.
        • return [значение]; - Прекращает выполнение цикла и выходит из функции.
        • continue; - Пропускает выполнение текущей итерации цикла.
        • Ключевые слова
          Ключевые слова
          - это слова, которые зарезервированы самим SourcePawn и их нельзя использовать, как имена переменных и фукнций.
          К ним относятся if, for, return и другие.
          Если вы попытаетесь использовать ключевые слова как имена переменных и функций то получите ошибку:
          error 173: 'слово' is a newly reserved keyword that may be used in the future; use a different name as an identifier
        • Инструкции компилятора
          Инструкции компилятора
          - это инструкции, которые нужны для компилятора. После компиляции их нет в исполняемом файле.
          Инструкции компилятора всегда начинаются с символа #
          • #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 - отключает)
<= К содержанию
 
Последнее редактирование:
Сверху Снизу