PDA

Просмотр полной версии : [Вопрос] Несколько вопросов (переменные, длина текста)



PawnoNoob
08.05.2017, 17:28
Приветствую! Появилось несколько вопросов, на которые я (из-за малого опыта в данной сфере) дать ответа не могу.

1. Длина текста в чате. Сразу скажу, что я знаю, что максимальная длина текста в чате равна 144 символам, но можно ли увеличить этот лимит? (самописную функцию какую-нибудь использовать, например).

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

new s_string[128], b_string[256]; // Глобальные переменные.
Или же так:

public test()
{
new string[100];
format(string, sizeof(string), "...", ...);
...
return true;
}

Если создавать глобальные переменные, то как их лучше использовать?

format(s_string, sizeof(s_string), "...", ...); // С sizeof
format(s_string, 50, "...", ...); // Или выделять определённое кол-во ячеек?

Nash_Brigers
08.05.2017, 18:00
1. Нет
2. Подвергну себя на лютые гонения, но скажу, что глобальную... Не знаю, почему все шумят, самп однопоточный, и в "стандартных случаях", лично я использую глобальный массив - за 2 года ни каких ошибок не заметил. Главное нормально использовать.... В теории правильнее использовать локальную переменную, но на практике - глобальную. Это моё мнение.
p.s. DC в этом плане против и ругается...

DeimoS
08.05.2017, 18:23
Длина текста в чате не 144, а 128 символов. Именно столько можно ввести в строку чата.
144 - это максимальное число символов, которые может вывести SendClientMessage(ToAll) за раз. Точнее, "144+1", если объявлять массив. А если ещё точнее - "MAX_CHATBUBBLE_LENGTH+1", дабы совместимость не потерять, в случае обновлений клиента и изменения лимитов.
Обойти ограничение чата нельзя (ну, точнее, придётся правки в SA-MP вносить).
А длинный текст можно вывести путём использования нескольких SendClientMessage(ToAll). Например:

public OnPlayerCommandText(playerid, cmdtext[])
{
if (strcmp("/test", cmdtext, true) == 0)
{
new text[] = "Длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный текст",
string[MAX_CHATBUBBLE_LENGTH+1],// Так как наш текст очень длинный, создадим своеобразный буфер, в который будем помещать куски текста, дабы сервер не завис
len = strlen(text),// Узнаём размер нашего текста
repeats = len/MAX_CHATBUBBLE_LENGTH;// Вычисляем насколько размер больше 144

format(string, sizeof(string), text); // Функцией формат поместим кусок текста в 144 символов из text в массив string
SendClientMessage(playerid, -1, string);// Выводим текст в чат
if(repeats)// Если текст больше 144, запускаем цикл и выводим оставшиеся части
{
for(new i = 1; i <= repeats; i++)
{
format(string, sizeof(string), text[MAX_CHATBUBBLE_LENGTH*i]);// Делаем то же самое, только теперь "отрезаем" текст не с нулевой ячейки, а с "144*номер_итерации". Таким образом мы выведем весь текст
SendClientMessage(playerid, -1, string);
}
}
format(string, sizeof(string), "Длина текста: %d | Число сообщений: %d", len, repeats+1);// Ну и ради интереса выведем полученн
SendClientMessage(playerid, -1, string);
return 1;
}
return 0;
}

А можно воспользоваться готовым решением (http://pro-pawn.ru/showthread.php?14024-zmessage-%D0%BC%D0%BD%D0%BE%D0%B3%D0%BE%D1%81%D1%82%D1%80%D0%BE%D1%87%D0%BD%D1%8B%D0%B5-%D1%81%D0%BE%D0%BE%D0%B1%D1%89%D0%B5%D0%BD%D0%B8%D1%8F)


На твоё усмотрение. Я предпочитаю использовать локальные переменные, дабы быть уверенным, что весь текст, с которым я работаю, будет целиком обработан.
С технической точки разница будет лишь в том, что в случае с локальными переменными ты работаешь с уже выделенной памятью (стэком) и ничего более не выделяешь, а глобальная переменная займёт место в сегменте данных. Это нисколько не критично.
Всё, в основном, упирается в удобство, ибо нужно будет постоянно помнить размер этого массива, дабы не забыть увеличит его в случае чего + теряется некая ясность в коде, ибо ты так сразу не сможешь понять, что раз вот тут у тебя объясляется массив, значит до этого никаких действий с данными не происходит.


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

new s_string[100];
format(s_string, 5, "123456789");
В этой ситуации ты всё так же обращаешься к массиву, состоящему из 100 ячеек. Просто функция format обрежет текст "123456789", оставив лишь первые 5 символов.

Пользы от ручного указания в обычной ситуации нет никакой. А вот проблемы могут начаться, если ты вдруг решишь уменьшить размер массива, но число оставишь прежним (случится выход за пределы массива, если текст будет слишком длинный)

PawnoNoob
08.05.2017, 19:18
Длина текста в чате не 144, а 128 символов. Именно столько можно ввести в строку чата.
144 - это максимальное число символов, которые может вывести SendClientMessage(ToAll) за раз. Точнее, "144+1", если объявлять массив. А если ещё точнее - "MAX_CHATBUBBLE_LENGTH+1", дабы совместимость не потерять, в случае обновлений клиента и изменения лимитов.
Обойти ограничение чата нельзя (ну, точнее, придётся правки в SA-MP вносить).
А длинный текст можно вывести путём использования нескольких SendClientMessage(ToAll). Например:

public OnPlayerCommandText(playerid, cmdtext[])
{
if (strcmp("/test", cmdtext, true) == 0)
{
new text[] = "Длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный-длинный текст",
string[MAX_CHATBUBBLE_LENGTH+1],// Так как наш текст очень длинный, создадим своеобразный буфер, в который будем помещать куски текста, дабы сервер не завис
len = strlen(text),// Узнаём размер нашего текста
repeats = len/MAX_CHATBUBBLE_LENGTH;// Вычисляем насколько размер больше 144

format(string, sizeof(string), text); // Функцией формат поместим кусок текста в 144 символов из text в массив string
SendClientMessage(playerid, -1, string);// Выводим текст в чат
if(repeats)// Если текст больше 144, запускаем цикл и выводим оставшиеся части
{
for(new i = 1; i <= repeats; i++)
{
format(string, sizeof(string), text[MAX_CHATBUBBLE_LENGTH*i]);// Делаем то же самое, только теперь "отрезаем" текст не с нулевой ячейки, а с "144*номер_итерации". Таким образом мы выведем весь текст
SendClientMessage(playerid, -1, string);
}
}
format(string, sizeof(string), "Длина текста: %d | Число сообщений: %d", len, repeats+1);// Ну и ради интереса выведем полученн
SendClientMessage(playerid, -1, string);
return 1;
}
return 0;
}

А можно воспользоваться готовым решением (http://pro-pawn.ru/showthread.php?14024-zmessage-%D0%BC%D0%BD%D0%BE%D0%B3%D0%BE%D1%81%D1%82%D1%80%D0%BE%D1%87%D0%BD%D1%8B%D0%B5-%D1%81%D0%BE%D0%BE%D0%B1%D1%89%D0%B5%D0%BD%D0%B8%D1%8F)


На твоё усмотрение. Я предпочитаю использовать локальные переменные, дабы быть уверенным, что весь текст, с которым я работаю, будет целиком обработан.
С технической точки разница будет лишь в том, что в случае с локальными переменными ты работаешь с уже выделенной памятью (стэком) и ничего более не выделяешь, а глобальная переменная займёт место в сегменте данных. Это нисколько не критично.
Всё, в основном, упирается в удобство, ибо нужно будет постоянно помнить размер этого массива, дабы не забыть увеличит его в случае чего + теряется некая ясность в коде, ибо ты так сразу не сможешь понять, что раз вот тут у тебя объясляется массив, значит до этого никаких действий с данными не происходит.


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

new s_string[100];
format(s_string, 5, "123456789");
В этой ситуации ты всё так же обращаешься к массиву, состоящему из 100 ячеек. Просто функция format обрежет текст "123456789", оставив лишь первые 5 символов.

Пользы от ручного указания в обычной ситуации нет никакой. А вот проблемы могут начаться, если ты вдруг решишь уменьшить размер массива, но число оставишь прежним (случится выход за пределы массива, если текст будет слишком длинный)


То есть по-вашему лучше использовать локальные переменные с подсчётом размера форматируемой строки (http://pro-pawn.ru/showthread.php?13388-Подсчёт-размера-форматируемой-строки)?

SooBad
08.05.2017, 19:25
То есть по-вашему лучше использовать локальные переменные с подсчётом размера форматируемой строки (http://pro-pawn.ru/showthread.php?13388-Подсчёт-размера-форматируемой-строки)?

P.S. Размер маленьких строк можно считать вручную, либо использовать сервисы по подсчёту символов(в некоторых редакторах это уже предусмотрено). При работе с большИм кол-вом спецификаторов следует использовать метод, описываемый DC. В принципе, можно всё вручную считать, но дорого ли такому человеку время?

DeimoS
08.05.2017, 19:46
То есть по-вашему лучше использовать локальные переменные с подсчётом размера форматируемой строки (http://pro-pawn.ru/showthread.php?13388-Подсчёт-размера-форматируемой-строки)?

Я использую локальные переменные и ручной (при помощи встроенной функции редактора (http://i.imgur.com/VvxDTZc.png)) подсчёт. А метод, что указан в статье по ссылке, я считаю слишком громоздким и гораздо более времязатратным, если учесть, что 99% всех текстов в скриптах будут правится лишь однажды - при написании этого самого скрипта. Ну, в лучшем случае, ещё пару раз. Поэтому не вижу смысла ради этого убивать читаемость кода (а она очень даже убивается) ради того, чтоб сэкономить время в ситуации, которая, скорее всего, никогда не настанет


В принципе, можно всё вручную считать, но дорого ли такому человеку время?

Меня всегда интересовал другой вопрос: куда спешат все те, кто сокращают имена нативок (а-ля: "format( -> f(" или "SendClientMessage -> SCM") и пользуются методами, подобными тому, что указан в статье, оправдывая это экономией времени? Всегда пишу весь код без каких-либо непонятных сокращений и, вроде, не отстал от остальных во времени (или отстал?). Может я жизнь не понял и неправильно живу?

PawnoNoob
08.05.2017, 19:50
Я использую локальные переменные и ручной (при помощи встроенной функции редактора (http://i.imgur.com/VvxDTZc.png)) подсчёт. А метод, что указан в статье по ссылке, я считаю слишком громоздким и гораздо более времязатратным, если учесть, что 99% всех текстов в скриптах будут правится лишь однажды - при написании этого самого скрипта. Ну, в лучшем случае, ещё пару раз. Поэтому не вижу смысла ради этого убивать читаемость кода (а она очень даже убивается) ради того, чтоб сэкономить время в ситуации, которая, скорее всего, никогда не настанет



Меня всегда интересовал другой вопрос: куда спешат все те, кто сокращают имена нативок (а-ля: "format( -> f(" или "SendClientMessage -> SCM") и пользуются методами, подобными тому, что указан в статье, оправдывая это экономией времени? Всегда пишу весь код без каких-либо непонятных сокращений и, вроде, не отстал от остальных во времени (или отстал?). Может я жизнь не понял и неправильно живу?

А что за редактор Вы используете? Atom (или я ошибаюсь?:sad:)

DeimoS
08.05.2017, 19:52
А что за редактор Вы используете? Atom (или я ошибаюсь?:sad:)

Sublime Text 3 (http://pro-pawn.ru/showthread.php?14620-%D0%A0%D0%B5%D0%B4%D0%B0%D0%BA%D1%82%D0%BE%D1%80-%D0%BA%D0%BE%D0%B4%D0%B0-%C2%ABSublime-Text-3%C2%BB-%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5-%D0%B2-Pawn-%28beta%29)

PawnoNoob
08.05.2017, 22:13
Sublime Text 3 (http://pro-pawn.ru/showthread.php?14620-%D0%A0%D0%B5%D0%B4%D0%B0%D0%BA%D1%82%D0%BE%D1%80-%D0%BA%D0%BE%D0%B4%D0%B0-%C2%ABSublime-Text-3%C2%BB-%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5-%D0%B2-Pawn-%28beta%29)

Исключается ли возможность "краша" или каких-либо других проблем при редактировании и компиляции кода, если адаптировать редактор под pawn по Вашей инструкции? (Ну, например, кодировка (символы всякие))

SooBad
08.05.2017, 22:26
Исключается ли возможность "краша" или каких-либо других проблем при редактировании и компиляции кода, если адаптировать редактор под pawn по Вашей инструкции? (Ну, например, кодировка (символы всякие))

Насколько я знаю, "вылеты" происходят только у стандартного компилятора. Сейчас тоже перешёл на ST3(иногда юзаю NotePad) - проблем не наблюдается уже в течении пары месяцев.
Насчёт кодировки - Unicode и ASCII точно поддерживает.

DeimoS
08.05.2017, 23:44
Исключается ли возможность "краша" или каких-либо других проблем при редактировании и компиляции кода, если адаптировать редактор под pawn по Вашей инструкции? (Ну, например, кодировка (символы всякие))

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

За всё время работы в нём (а это уже, наверное, года три-четыре), у меня были проблемы лишь в самом начале, да и то, дело бы не в редакторе, а в том, что я его не настроил как следует (как раз с кодировкой и были проблемы). Сейчас же проблем вообще нет никаких и я не совсем понимаю, как я раньше мог писать код в Pawno, который разве что подсветкой синтаксиса отличается от обычного блокнота.

И да. Если уж хочется максимально обезопасить свои наработки, то можно установить плагин, который будет автоматически делать бэкапы (хоть в указанную папку, хоть на указанный репозиторий зальёт). Благо сейчас плагинов настолько много, что можно найти решение любой проблемы. А если даже покажется, что этого решения нет в сети, его можно легко написать самому (благо плагины пишутся довольно легко).

Nexius_Tailer
09.05.2017, 00:11
В теории правильнее использовать локальную переменную, но на практике - глобальную. Это моё мнение.
p.s. DC в этом плане против и ругается...
На одного человека ругается больше, на одного меньше. А если судить по объективным причинам, то это немного как с goto - юзая в ситуациях, где это не необходимо, никакого реального профита человек не вынесет, а лишь запутает свой код и повысит шансы на допущение ошибок.
С наличием глобальной переменной нужно всегда следить, чтобы она вовремя форматировалась и полностью перезаписывалась новыми данными (особенно актуально, если к ней применяются ещё и strcat и прочие, которые её не чистят), да ещё и в памяти почти всегда, когда нужна она там ненадолго, но это уже не так важно. С локальной же можно быть уверенным: в каком блоке (теле) её объявил - в том она и проработает, и по повторному вызову функции можно быть также полностью уверенным, что строка чистая.

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


P.S. Размер маленьких строк можно считать вручную, либо использовать сервисы по подсчёту символов(в некоторых редакторах это уже предусмотрено). При работе с большИм кол-вом спецификаторов следует использовать метод, описываемый DC. В принципе, можно всё вручную считать, но дорого ли такому человеку время?
А я вот немного не понимаю. С изменением текста, как правило, меняется и его содержание, и его длина, и количество этих спецификаторов, что в итоге требует и правок формул подсчётов. Тем самым, смысл от такого удобства сомнительный. Хотя возможно кому-то и заходит...

SooBad
09.05.2017, 00:32
А я вот немного не понимаю. С изменением текста, как правило, меняется и его содержание, и его длина, и количество этих спецификаторов, что в итоге требует и правок формул подсчётов. Тем самым, смысл от такого удобства сомнительный. Хотя возможно кому-то и заходит...
С локальным массивом то же самое.
Придётся вручную подсчитывать добавленные символы и втюхивать в массив недостающее кол-во ячеек.
Профита также нет.
Глобальный массив - это уже что-то из оперы RLS...
Единственное возможное применение вижу только в форматировании строк просто гигантских размеров, типо сводок общих правил и подобного. Хотя даже тут, можно банально скрепить строки, разбив общий массив для форматирования на несколько локальных.

DeimoS
09.05.2017, 01:00
С локальным массивом то же самое.
Придётся вручную подсчитывать добавленные символы и втюхивать в массив недостающее кол-во ячеек.
Профита также нет.

Nexius имел ввиду то, что вариант, описанный Кортезом, не так хорош на деле, как о нём кричат ярые защитники.
Особенно радует, когда таким вот методом пытаются подсчитать строку из 10 символов, которую больше никогда не будут редактировать в дальнейшем (если зайти на п-и в раздел команд, можно кучу примеров найти этого ужаса).
Или когда массив с текстом объявляется в одном месте, а сам format через несколько строк ниже. И мало того, что все параметры начинают сливаться

//

format(string, sizeof(string), fmt_str, playerid, string, playerid, string, playerid, string);// Вот это разве удобно? Чтоб понять где находится третий параметр, нужно прилично так вглядываться. А если рядом будет другой код - всё ещё плачевней становится

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


Единственное возможное применение вижу только в форматировании строк просто гигантских размеров, типо сводок общих правил и подобного. Хотя даже тут, можно банально скрепить строки, разбив общий массив для форматирования на несколько локальных.

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

Nexius_Tailer
09.05.2017, 01:12
С локальным массивом то же самое.
Придётся вручную подсчитывать добавленные символы и втюхивать в массив недостающее кол-во ячеек.
Профита также нет.
На опыте лично для себя нашёл оптимальный вариант: выделять заведомо чуть больше. Для удобства это чаще всего числа, являющиеся степенью двойки (16, 32, 64, 128) для не очень больших строк, где этот хвост из пустых ячеек ни на что не повлияет. А считать более точно резонно уже более громоздкие массивы, да и то можно, как уже сказал выше, объявить через static и не париться. Так что профит от точного подсчёта ячейка в ячейку вообще в принципе под вопросом, если уж так рассуждать.

SooBad
09.05.2017, 01:30
Nexius имел ввиду то, что вариант, описанный Кортезом, не так хорош на деле, как о нём кричат ярые защитники.
Особенно радует, когда таким вот методом пытаются подсчитать строку из 10 символов, которую больше никогда не будут редактировать в дальнейшем (если зайти на п-и в раздел команд, можно кучу примеров найти этого ужаса).
Или когда массив с текстом объявляется в одном месте, а сам format через несколько строк ниже. И мало того, что все параметры начинают сливаться

//
format(string, sizeof(string), fmt_str, playerid, string, playerid, string, playerid, string);// Вот это разве удобно? Чтоб понять где находится третий параметр, нужно прилично так вглядываться. А если рядом будет другой код - всё ещё плачевней становится
//
так ещё и приходится постоянно сверяться с текстом массива, дабы определить, совпадает ли порядок спецификаторов с порядком переменных. И постоянно приходится выискивать нужную переменную/спецификатор, ибо чем больше их становится, тем труднее сходу ориентироваться в этой каше кода.
В общем, этот метод нужно использовать исключительно там, где он будет полезен, а не везде, где только можно. Ибо чаще получается так, что и подсчитать вручную было бы быстрее размер, и код впустую раздулся на несколько лишних строк.
Это лучше делать локально и с применением static. Выискивать глобальный массив, что находится за сотню-другую строк от его места применения - такое себе удовольствие.

Так я про то же самое и писал)


На опыте лично для себя нашёл оптимальный вариант: выделять заведомо чуть больше. Для удобства это чаще всего числа, являющиеся степенью двойки (16, 32, 64, 128) для не очень больших строк, где этот хвост из пустых ячеек ни на что не повлияет. А считать более точно резонно уже более громоздкие массивы, да и то можно, как уже сказал выше, объявить через static и не париться. Так что профит от точного подсчёта ячейка в ячейку вообще в принципе под вопросом, если уж так рассуждать.

Правда инициализация пустых ячеек будет занимать на пару микросекунд дольше
Так суть-то и в том, что это многовариационный момент. Автор спрашивает про удобство конкретного способа. Но порой, даже задействование метода, описанного DC - будет не менее комфортным. Ну, по крайней мере в плане экономии времени, особенно при подсчёте строк длинной в 150-200 а то и больше символов (зависит от ситуации).
Наиболее рациональный вариант - редактор. Можно даже перенаполнять массив лишними ячейками(как ты и говоришь), не вычитая длину спецификаторов, а лишь прибавляя величину их макс.значения.

Daniel_Cortez
09.05.2017, 01:40
Ок, я обновил свой урок по подсчёту размера форматного массива (http://pro-pawn.ru/showthread.php?13388), добавив список преимуществ/недостатков метода, а также добавил советы по поводу того, где подсчёт следует использовать, а где он будет лишним.

Буду рад услышать ваше мнение, если не согласны по какому-либо из критериев в добавленном списке. И да, спасибо всем тем в этой теме, кто предоставил критику по поводу того метода.


Касаемо глобальных/локальных массивов, во многих случаях можно обойтись локальными. Рассмотрим это на примере команды /admins, выводящей список админов онлайн.
Стандартный размер секции стека/кучи в Pawn - 16384 байт или 4096 ячеек. Из них будет безопасно взять 4000 под массив для выводимого текста - остальные 96 оставим под цепочку вызовов (OnPlayerCommandText -> [командный процессор] -> CMD:admins) и прочие "непредвиденные расходы". Если же массивов больше одного, то их суммарный размер должен быть не более 4000.
SendClientMessage и ShowPlayerDialog прекрасно понимают упакованные строки - так почему же не использовать их? В результате емкость увеличится в 4 раза и в итоге ёмкость составит примерно 16000 символов.

Nexius_Tailer
09.05.2017, 02:26
Можно даже перенаполнять массив лишними ячейками(как ты и говоришь), не вычитая длину спецификаторов, а лишь прибавляя величину их макс.значения.
С этим ничего по сути не изменится. При изменении строки, в т.ч. добавлении спецификаторов тебе всё равно нужно будет что-то прибавлять, что в итоге выйдет той же формулой, просто без отниманий их длин


Касаемо глобальных/локальных массивов, во многих случаях можно обойтись локальными. Рассмотрим это на примере команды /admins, выводящей список админов онлайн.
Стандартный размер секции стека/кучи в Pawn - 16384 байт или 4096 ячеек. Из них будет безопасно взять 4000 под массив для выводимого текста - остальные 96 оставим под цепочку вызовов (OnPlayerCommandText -> [командный процессор] -> CMD:admins) и прочие "непредвиденные расходы". Если же массивов больше одного, то их суммарный размер должен быть не более 4000.
SendClientMessage и ShowPlayerDialog прекрасно понимают упакованные строки - так почему же не использовать их? В результате емкость увеличится в 4 раза и в итоге ёмкость составит примерно 16000 символов.

Оно-то можно, но иногда реально проще и быстрее просто объявить через static и не опасаться того, что появись в этот момент где-то в этой области ещё пара подобных массивов, и все перестраховки в свой лимит на 4000 будут абсолютно бесполезными. И конечно в такой ситуации виноват будет скриптер, потому что недоглядел, но сам факт того, что это надёжнее и требует меньше телодвижений уже кажется более оптимальным вариантом. Но это касаемо реально больших массивов

Daniel_Cortez
09.05.2017, 15:41
Оно-то можно, но иногда реально проще и быстрее просто объявить через static и не опасаться того, что появись в этот момент где-то в этой области ещё пара подобных массивов, и все перестраховки в свой лимит на 4000 будут абсолютно бесполезными.
Я этого и не отрицал. Собственно, в этом и заключается дилема: оптимальный расход ресурсов против удобства. Нет единственно верного решения, выбор должен строиться индивидуально для каждого случая.