Спецификаторы аргументов — различия между версиями

Материал из Pro-Pawn Wiki
Перейти к: навигация, поиск
(Новая страница: «{{Description | Спецификаторы для обозначения типов аргументов в функциях <code>SetTimerEx()</code>, <code>…»)
 
 
(не показана одна промежуточная версия этого же участника)
Строка 2: Строка 2:
 
| Спецификаторы для обозначения типов аргументов в функциях <code>[[SetTimerEx]]()</code>, <code>[[CallLocalFunction]]()</code> и <code>[[CallRemoteFunction]]()</code>.
 
| Спецификаторы для обозначения типов аргументов в функциях <code>[[SetTimerEx]]()</code>, <code>[[CallLocalFunction]]()</code> и <code>[[CallRemoteFunction]]()</code>.
 
}}
 
}}
* <code>a</code> - массив.<br/><nowiki>
+
{| class="wikitable"
</nowiki>При использовании данного спецификатора после самого массива следует также передавать его размер, а после спецификатора <code>a</code> добавить ещё один спецификатор (любой, кроме <code>a</code> и <code>s</code>).<pawn>
+
! Спецификатор(ы)
public MyFunction(const array[], size);
+
! Значение
public MyFunction(const array[], size)
+
! Примечание
 +
|-
 +
| <code>s</code>
 +
| Строка
 +
|
 +
|-
 +
| <code>a</code>
 +
| Массив
 +
| Следующим аргументом должен быть размер массива (со спецификатором <code>d</code>/<code>i</code> или любым другим, отличным от <code>a</code> и <code>s</code>).
 +
|-
 +
| <code>d</code>, <code>i</code>
 +
| Целое число
 +
|
 +
|-
 +
| <code>f</code>
 +
| Вещественное число
 +
|
 +
|-
 +
| <code>b</code>
 +
| Логическое значение
 +
|
 +
|-
 +
| <code>c</code>
 +
| Символ
 +
|
 +
|}
 +
 
 +
 
 +
{{NoteInfo
 +
| Только у спецификаторов <code>a</code> и <code>s</code> есть чёткая функция. Спецификаторы <code>d</code>, <code>i</code>, <code>f</code>, <code>b</code> и <code>c</code> нужны только для читаемости кода - на самом деле сервер их не различает и кроме них могут работать любые другие символы, отличные от <code>a</code> и <code>s</code>.
 +
<pawn>
 +
forward MyFunction(a, b, c);
 +
public MyFunction(a, b, c)
 
{
 
{
printf("Размер массива: %d", size);
+
    printf("%d, %d, %d", a, b, c);
for (new i = 0; i < size; ++i)
+
printf("\tarray[%d]: 0x%08x", i, array[i]);
+
 
}
 
}
  
 
public OnGameModeInit()
 
public OnGameModeInit()
 
{
 
{
static const array[] = { 0x00112233, 0x44556677, 0x8899AABB };
+
    CallLocalFunction("MyFunction", "xyz", 1, 2, 3);
CallLocalFunction("MyFunction", "ai", array, sizeof(array));
+
    CallLocalFunction("MyFunction", "абв", 4, 5, 6);
 +
    CallLocalFunction("MyFunction", "+-=", 7, 8, 9);
 
}
 
}
</pawn><br/>
+
</pawn>
 +
}}
 +
{{NoteSAMPBug
 +
| При передаче в <code>[[SetTimerEx]]()</code> массивов и строк (спецификаторы <code>a</code> и <code>s</code> соответственно) под них резервируется память в секции стека/кучи скрипта, однако эта память не высвобождается при уничтожении таймера. Многократное создание таймеров с передачей строк или массивов может привести к ошибкам времени выполнения из-за исчерпания свободного места в секции стека/кучи - первопричину такой ошибки очень трудно определить, если не знать о данном баге.
 +
| При передаче через <code>[[SetTimerEx]]()</code> строка может оказаться повреждена.
 +
}}
  
* <code>s</code> - строка.<pawn>
+
{{Example}}
public MyFunction(const string[]);
+
<pawn>
public MyFunction(const string[])
+
forward ArrayFunction(const array[], size);
 +
public ArrayFunction(const array[], size)
 
{
 
{
printf("string: %s", string);
+
printf("Размер массива: %d", size);
 +
for (new i = 0; i < size; ++i)
 +
printf("\tarray[%d]: 0x%08x", i, array[i]);
 
}
 
}
  
public OnGameModeInit()
+
forward StringFunction(const string[]);
 +
public StringFunction(const string[])
 
{
 
{
CallLocalFunction("MyFunction", "s", "abc");
+
    printf("string: %s", string);
 
}
 
}
</pawn><br/>
 
  
* Любой другой символ - ячейка Pawn (целочисленное значение, вещественное число и пр.)<pawn>
+
forward ThreeArgFunction(a, Float:b, bool:c);
public MyFunction(a, b, c);
+
public ThreeArgFunction(a, Float:b, bool:c)
public MyFunction(a, b, c)
+
 
{
 
{
printf("%d, %d, %d", a, b, c);
+
    printf("%d, %f, %s", a, b, c ? ("true") : ("false"));
 
}
 
}
  
 
public OnGameModeInit()
 
public OnGameModeInit()
 
{
 
{
// Наиболее частыми являются спецификаторы "i", "d" и "f".
+
static const array[] = { 0x00112233, 0x44556677, 0x8899AABB };
CallLocalFunction("MyFunction", "iii", 1, 2, 3);
+
CallLocalFunction("ArrayFunction", "ai", array, sizeof(array));
  
// Но на самом деле сервер их не различает и кроме них
+
CallLocalFunction("StringFunction", "s", "abc");
// работают любые символы, отличные от "a" и "s".
+
CallLocalFunction("MyFunction", "абв", 4, 5, 6);
+
  
// Даже знаки препинания - все они работают одинаково.
+
CallLocalFunction("ThreeArgFunction", "ifb", 1, 2.0, false);
CallLocalFunction("MyFunction", "+-=", 7, 8, 9);
+
 
}
 
}
 
</pawn>
 
</pawn>
 
 
{{NoteSAMPBug
 
| При передаче в <code>[[SetTimerEx]]()</code> массивов и строк (спецификаторы <code>a</code> и <code>s</code> соответственно) под них резервируется память в секции стека/кучи скрипта, однако эта память не высвобождается при уничтожении таймера. Многократное создание таймеров с передачей строк или массивов может привести к ошибкам времени выполнения из-за исчерпания свободного места в секции стека/кучи - первопричину такой ошибки очень трудно определить, если не знать о данном баге.
 
| При передаче через <code>[[SetTimerEx]]()</code> строка может оказаться повреждена.
 
}}
 
 
{{SeeAlso}}
 
{{SeeAlso}}
 
* [[SetTimerEx]]
 
* [[SetTimerEx]]

Текущая версия на 18:34, 6 октября 2018

Описание:

Спецификаторы для обозначения типов аргументов в функциях SetTimerEx(), CallLocalFunction() и CallRemoteFunction().

Спецификатор(ы) Значение Примечание
s Строка
a Массив Следующим аргументом должен быть размер массива (со спецификатором d/i или любым другим, отличным от a и s).
d, i Целое число
f Вещественное число
b Логическое значение
c Символ


Info rhombus.png
Примечание
Только у спецификаторов a и s есть чёткая функция. Спецификаторы d, i, f, b и c нужны только для читаемости кода - на самом деле сервер их не различает и кроме них могут работать любые другие символы, отличные от a и s.
forward MyFunction(a, b, c);
public  MyFunction(a, b, c)
{
    printf("%d, %d, %d", a, b, c);
}

public OnGameModeInit()
{
    CallLocalFunction("MyFunction", "xyz", 1, 2, 3);
    CallLocalFunction("MyFunction", "абв", 4, 5, 6);
    CallLocalFunction("MyFunction", "+-=", 7, 8, 9);
}


Bug.png
Баг SA-MP
При передаче в SetTimerEx() массивов и строк (спецификаторы a и s соответственно) под них резервируется память в секции стека/кучи скрипта, однако эта память не высвобождается при уничтожении таймера. Многократное создание таймеров с передачей строк или массивов может привести к ошибкам времени выполнения из-за исчерпания свободного места в секции стека/кучи - первопричину такой ошибки очень трудно определить, если не знать о данном баге.
При передаче через SetTimerEx() строка может оказаться повреждена.


Пример использования:

forward ArrayFunction(const array[], size);
public  ArrayFunction(const array[], size)
{
    printf("Размер массива: %d", size);
    for (new i = 0; i < size; ++i)
        printf("\tarray[%d]: 0x%08x", i, array[i]);
}

forward StringFunction(const string[]);
public  StringFunction(const string[])
{
    printf("string: %s", string);
}

forward ThreeArgFunction(a, Float:b, bool:c);
public  ThreeArgFunction(a, Float:b, bool:c)
{
    printf("%d, %f, %s", a, b, c ? ("true") : ("false"));
}

public OnGameModeInit()
{
    static const array[] = { 0x00112233, 0x44556677, 0x8899AABB };
    CallLocalFunction("ArrayFunction", "ai", array, sizeof(array));

    CallLocalFunction("StringFunction", "s", "abc");

    CallLocalFunction("ThreeArgFunction", "ifb", 1, 2.0, false);
}


См. также: