Question

В format и sscanf есть конструкция "{Float, _}:...". Первую часть конструкции я понимаю, теги. Но что значит "..."? Можно ли эту конструкцию использовать в своих функциях, и как обращатся к ней? Я в какой-то функции видел "Float:oper1, ...", получается, нужно обращатся через oper1, oper2, oper3?

Share this post


Link to post

2 answers to this question

  • 0

{Float,_}:.. обозначает неопределённое кол-во параметров, к примеру в том же использовании sscanf при вводе команды:

/goto 36 // тут только 1 параметр
/sethp 36 0 // тут уже 2 параметра

Не думаю, что это можно использовать в ваших фанкция (вроде как {Float,_}:.. идёт только для плагинов), но вы можете использовать вместо этого массив:

stock multiprint(texts[])
{
    for(i = 0; i < sizeof texts; i++) {
        print(texts[i]);
    } return 1;
}
// use:
main() {
    new a = rand(110);
    multiprint({1"asd", a, 32.7});
    return 1;
}

Вроде так

Share this post


Link to post
  • 0
1 час назад, Sleash сказал:

вроде как {Float,_}:.. идёт только для плагинов

Есть лишь одна синтаксема языка Pawn, которая не имеет никакого смысла без подключения сторонних программ, и эта синтаксема – ключевое слово native.

 

9 часов назад, KlasterK сказал:

{Float, _}:...

Для начала имеет смысл сказать пару слов о тегах. Для того, чтобы переменная или параметр функции могли принимать значение, принадлежащее определенному множеству значений, на уровне компилятора есть такая замечательная вещь как теги, использование которых, очевидно, помогает защитить себя от непреднамеренных ошибок. По умолчанию у всех переменных есть тег "_:", написание которого необязательно. Однако вы можете создавать свои собственные теги, чтобы, как уже было сказано, ограничить множество принимаемых значений.

 

В примере ниже реализована программа, создающая множество фигур, чтобы позволить тегированным переменным принимать значения из этого множества. В окне консоли можно увидеть слово "Круг".

Спойлер

#include <a_samp>



enum EShape: {
    CIRCLE = 0,
    TRIANGLE,
    SQUARE,
    OVAL
};

main() {
    new EShape:eShape = CIRCLE;
    
    switch (eShape) {
        case CIRCLE: {
            print("Круг");
        }
        case TRIANGLE: {
            print("Треугольник");
        }
        case SQUARE: {
            print("Квадрат");
        }
        default: {
            print("Неизвестная фигура");
        }
    }
}

 

 

Отмечу, что присвоение тегированной переменной значения, не входящего в множество допустимых значений, влечет предупреждение компилятора о несовпадении тегов (tag mismatch). Однако, несмотря на предупреждение, переменная eShape получает значение SOME_VALUE2, эквивалентное нулю (что совпадает со значением TRIANGLE), и в окне консоли мы видим слово "Треугольник".

Спойлер

#include <a_samp>


enum EShape: {
    CIRCLE = 0,
    TRIANGLE,
    SQUARE,
    OVAL
};

enum ESomeEnum: {
    SOME_VALUE1 = 0,
    SOME_VALUE2
};

main() {
    new EShape:eShape = SOME_VALUE2;
    
    switch (eShape) {
        case CIRCLE: {
            print("Круг");
        }
        case TRIANGLE: {
            print("Треугольник");
        }
        case SQUARE: {
            print("Квадрат");
        }
        default: {
            print("Неизвестная фигура");
        }
    }
}

 

 

Кроме того, можно попытаться присвоить и литерал. Однако в приведенном ниже примере вы все также можете увидеть предупреждение компилятора о несовпадении тегов. В окне консоли можно увидеть слово "Овал".

Спойлер

#include <a_samp>


enum EShape: {
    CIRCLE = 0,
    TRIANGLE,
    SQUARE,
    OVAL
};

enum ESomeEnum: {
    SOME_VALUE1 = 0,
    SOME_VALUE2
};

main() {
    new EShape:eShape = 3;
    
    switch (eShape) {
        case CIRCLE: {
            print("Круг");
        }
        case TRIANGLE: {
            print("Треугольник");
        }
        case SQUARE: {
            print("Квадрат");
        }
        case OVAL: {
            printf("Овал");
        }
        default: {
            print("Неизвестная фигура");
        }
    }
}

 

 

Кроме того, можно попытаться смешать тегированные и нетегированные переменные, что также повлечет предупреждение компилятора, но в целом будет работать. В окне консоли можно увидеть слово "Квадрат".

Спойлер

#include <a_samp>


enum EShape: {
    CIRCLE = 0,
    TRIANGLE,
    SQUARE,
    OVAL
};

enum ESomeEnum: {
    SOME_VALUE1 = 0,
    SOME_VALUE2
};

main() {
    new EShape:eShape = CIRCLE + 1// 0 + 1 + 1 = 2
    
    switch (eShape) {
        case CIRCLE: {
            print("Круг");
        }
        case TRIANGLE: {
            print("Треугольник");
        }
        case SQUARE: {
            print("Квадрат");
        }
        case OVAL: {
            printf("Овал");
        }
        default: {
            print("Неизвестная фигура");
        }
    }
}

 

 

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

new EShape:eShape = CIRCLE + EShape:1 + 1// 0 + 1 + 1 = 2

В случае, если вы хотите выполнить сравнение двух переменных, имеющих разные теги, вы также можете привести их к общему тегу (например, тег по умолчанию):

Спойлер

new EShape:eShape = CIRCLE;
new ESomeEnum:eSomeEnum = SOME_VALUE1;

if (_:eShape == _:eSomeEnum) {
    print("Equals!");
}
else {
    print("Not equals");
}

if (EShape:eShape == EShape:eSomeEnum) {
    print("Equals!");
}
else {
    print("Not equals");
}

if (eShape == EShape:eSomeEnum) {
    print("Equals!");
}
else {
    print("Not equals");
}

 

 

 

Кроме того, из школьного курса математики вам должно быть известно, что фигурные скобки есть множество, а элементы внутри этих скобок – элементы множества. Выражение "{Float,_}:" содержит множество тегов, которые могут быть получены как аргументы функции. Вам ничто не мешает вписать в это множество и свои собственные теги:

someFunction({Float,_,EShape, ESomeEnum}:...) {
    // тело функции
}

main() {

    new EShape:eShape = CIRCLE;
    new ESomeEnum:eSomeEnum = SOME_VALUE1;

    someFunction(eShape, eSomeEnum);
}

Кроме того, вы можете и не перечислять все теги, что не понравится компилятору: он выдаст предупреждение, поскольку функция не ожидает получить на вход переменные, снабженные неизвестными для нее тегами.

someFunction({Float,_}:...) {
    // тело функции
}

main() {

    new EShape:eShape = CIRCLE;
    new ESomeEnum:eSomeEnum = SOME_VALUE1;

    someFunction(eShape, eSomeEnum);
}

Однако для разрешения возникшей проблемы можно просто привести переменные к тегу по умолчанию:

someFunction({Float,_}:...) {
    // тело функции
}

main() {

    new EShape:eShape = CIRCLE;
    new ESomeEnum:eSomeEnum = SOME_VALUE1;

    someFunction(_:eShape, _:eSomeEnum);
}

 

Теперь что касается самих параметров. Как вы уже могли заметить по функциям вроде printf, SendClientMessage и прочим – все они могут получать на вход переменное число аргументов: либо ни одного, либо не меньше некоторого натурального числа N. Поскольку программист на этапе написания программы и сам не имеет понятия, сколько аргументов в конкретном случае будет передано в функцию, работа с параметрами функции идет посредством обращения в стек: указываем порядковый номер параметра и вытаскиваем из стека значение этого параметра. Узнать, сколько передано параметров в функцию, можно при помощи функции numargs, а обратиться к некоторому параметру – с помощью функции getarg. Ниже приведен пример использования функции с переменным числом аргументов.

 

Спойлер

someFunction(const types[], const size = sizeof(types), {Float,_}:...) {
    new lastCheckedArg = 2;

    for (new i = 0; i < size - 1; i++) {
        if (types[i] == 'd') { // рассматриваем число
            printf("%d", getarg(lastCheckedArg));
        }
        else if (types[i] == 's') { // рассматриваем строку
            new nIdxs = types[i + 1] - '0';

            for (new j = 0; j < nIdxs; j++) {
                printf("%c", getarg(lastCheckedArg, j));
            }

            i++; // также мы посмотрели размер, так что переходим далее
        }
        else if (types[i] == 'f') { // рассматриваем вещественное число
            printf("%f", getarg(lastCheckedArg));
        }
        else {
            print("Unknown param");
            break;
        }
        
        lastCheckedArg++; // переходим к следующему аргументу
    }
}

main() {
    someFunction("ddds5s1s3f", _, 23082023"pawno""-""rus"777.555);
}

 

 

Результат в консоли представлен далее.

Спойлер

23
8
2023
p
a
w
n
o
-
r
u
s
777.554992

 

 

Но, будем честны, мне сложно представить ситуацию, при которой появляется необходимость в написании функции с переменным числом аргументов.

Share this post


Link to post
This topic is now closed to further replies.
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By danya_white
      Доброго времени суток, сегодня выкладываю на продажу оригинальный игровой мод проекта Flin Mobile
      Данный игровой мод сейчас стоит на данном проекте, и держит стабильный онлайн.
       
      Информация о моде:
      Версия MYSQL - R41-4
      Античит - Nex-AC + Rakcheat (Настроено все)
      Стример - Streamer Plugin v2.9.4 by Incognito
      Командный процессор - Pawn CMD
      Хэширование паролей - MD5
      Остальное Все плагины обновлены до последней версии
       
      - Цена бочки снижена до 6000 тысяч вирт. - Навык влияет на ЗП. На 50 навыке продажа бочки за 13500(7500 чистыми) + надбавки за VIP, личный т/с. - Исправлен обход на количество бочек в час, теперь 25, ещё +25 с ADD VIP(в сумме 50). - Исправлено выбрасывание из автомобиля, когда игроки застревали в DFT-30. *Исправление для всех видов т/с. - Теперь когда начинаете загрузку/выгрузку вас не выбрасывает из автомобиля, нужно самому выйти. Подкорректирона работа anti +С. - Блокируется только +С и авто +С . - Сбив темпа работает. Снизили стоимость доступа. Теперь вы можете открывать контейнеры в любое время. Обновили список выпадающих предметов (окупиться или пойти в минус - все зависит от вашего везения). Добавили несколько Real Skins в контейнеры GOLD класса. Кроме того, мы добавили государственным структурам новую крутую штуку - нейтрализатор (нужен дробовик ID:25),  который позволяет быстро вывести из строя двигатель на рандомное время, что позволит полиции более эффективно выполнять свою работу и задерживать преступников. - Добавлены машины Ferrari F50 и Pegassi Toreto для погони за преступниками. - Добавление команды /сtazer для переключения между USP и Deagle. - Добавление нелетального дробовика SPAS, который парализует на 10-15 секунд. - Добавление кнопки паники (/panic) для вызова поддержки. - Фракция Police RC переименована в Los Santos Sheriff Departament (LSSD) - Доработка нейтрализатора автомобилей. - Добавлен семейный инвентарь. - Добавили команды /makegun и еще короткие команды для быстрого создания + /de /mp5 /ak47 /m4. - Добавили возможности отдавать свой личный Т/С в семью. - Добавлена команда /fonline для просмотра количества воюющих семей в онлайне. - Были заблокированы читы, которые позволяли читерам стрелять с большой скоростью - Внесены исправления и корректировки в работе нефтяника. - Изменена система контейнеров, можно открывать в любое время, так же добавлены все новые RealSkins. - Возвращены старые анимации по командам (например: /crossarms, /crossfingers, /frontfall и т.д). - Добавлены новые RP-команды (/ame, /ab, /(un)blind). - Добавлены команды для быстрого крафта оружия (/de /mp4 /m4 /ak47). - Добавлено блокирование предметов от 2 до 6 часов после их выбрасывания в мусорный бак. - Исправлена недоработка, когда можно было находиться в Т/С на ЦР. - Исправлена команда /lock, которая иногда не работала. - Исправлена проблема с меткой сдачи автомобиля на работе автоугонщика. - Исправлена причина кика игроков с ПК на работе нефтяника. Причина была в наличии посторонних CLEO/ASI у игроков. - Исправлена система посадки на мебель. - Увеличен шанс выигрыша ценных призов в рулетках , так же добавлены все новые Real Skins. - Исправлено отображение CJ скина в инвентаре на ПК. - Новая система "Карта кладов"  
    • By danya_white


      Скачать файл Игровой Мод Flin RP (последняя версия)
      Доброго времени суток, сегодня выкладываю на продажу оригинальный игровой мод проекта Flin Mobile
      Данный игровой мод сейчас стоит на данном проекте, и держит стабильный онлайн.
       
      Информация о моде:
      Версия MYSQL - R41-4
      Античит - Nex-AC + Rakcheat (Настроено все)
      Стример - Streamer Plugin v2.9.4 by Incognito
      Командный процессор - Pawn CMD
      Хэширование паролей - MD5
      Остальное Все плагины обновлены до последней версии
       
      - Цена бочки снижена до 6000 тысяч вирт. - Навык влияет на ЗП. На 50 навыке продажа бочки за 13500(7500 чистыми) + надбавки за VIP, личный т/с. - Исправлен обход на количество бочек в час, теперь 25, ещё +25 с ADD VIP(в сумме 50). - Исправлено выбрасывание из автомобиля, когда игроки застревали в DFT-30. *Исправление для всех видов т/с. - Теперь когда начинаете загрузку/выгрузку вас не выбрасывает из автомобиля, нужно самому выйти. Подкорректирона работа anti +С. - Блокируется только +С и авто +С . - Сбив темпа работает. Снизили стоимость доступа. Теперь вы можете открывать контейнеры в любое время. Обновили список выпадающих предметов (окупиться или пойти в минус - все зависит от вашего везения). Добавили несколько Real Skins в контейнеры GOLD класса. Кроме того, мы добавили государственным структурам новую крутую штуку - нейтрализатор (нужен дробовик ID:25),  который позволяет быстро вывести из строя двигатель на рандомное время, что позволит полиции более эффективно выполнять свою работу и задерживать преступников. - Добавлены машины Ferrari F50 и Pegassi Toreto для погони за преступниками. - Добавление команды /сtazer для переключения между USP и Deagle. - Добавление нелетального дробовика SPAS, который парализует на 10-15 секунд. - Добавление кнопки паники (/panic) для вызова поддержки. - Фракция Police RC переименована в Los Santos Sheriff Departament (LSSD) - Доработка нейтрализатора автомобилей. - Добавлен семейный инвентарь. - Добавили команды /makegun и еще короткие команды для быстрого создания + /de /mp5 /ak47 /m4. - Добавили возможности отдавать свой личный Т/С в семью. - Добавлена команда /fonline для просмотра количества воюющих семей в онлайне. - Были заблокированы читы, которые позволяли читерам стрелять с большой скоростью - Внесены исправления и корректировки в работе нефтяника. - Изменена система контейнеров, можно открывать в любое время, так же добавлены все новые RealSkins. - Возвращены старые анимации по командам (например: /crossarms, /crossfingers, /frontfall и т.д). - Добавлены новые RP-команды (/ame, /ab, /(un)blind). - Добавлены команды для быстрого крафта оружия (/de /mp4 /m4 /ak47). - Добавлено блокирование предметов от 2 до 6 часов после их выбрасывания в мусорный бак. - Исправлена недоработка, когда можно было находиться в Т/С на ЦР. - Исправлена команда /lock, которая иногда не работала. - Исправлена проблема с меткой сдачи автомобиля на работе автоугонщика. - Исправлена причина кика игроков с ПК на работе нефтяника. Причина была в наличии посторонних CLEO/ASI у игроков. - Исправлена система посадки на мебель. - Увеличен шанс выигрыша ценных призов в рулетках , так же добавлены все новые Real Skins. - Исправлено отображение CJ скина в инвентаре на ПК. - Новая система "Карта кладов"  
      Добавил danya_white Добавлено 10.12.2023 Категория Моды Автор danya_white  
    • By zdfgdhdrhrhd
      Доброго времени суток, столкнулся с проблемой при добавлении системы анти-флуда пикапов.
      По сути, она работает нормально, но немного напрягает тот факт, что когда встаешь на любой пикап, он отправляет сообщение по два раза, вместо одного.
      Знающие люди, помогите пожалуйста, заранее огромное спасибо!
      Откуда брал систему (инклуд прикрепил ниже):
      pickup_stop_flood.inc