переменная -
FaGo - 13.08.2016
Код из одного мода,скачал чтобы просто тупо осмотреться и узнать кое-что новое.
PHP код:
CMD:admins(playerid, params[])
{
new ttext[35], stringer1[500];
stringer = "";
foreach(new i : Player)
{
if (!IsPlayerConnected(i) || IsPlayerNPC(i) || (p_info[i][bAdmin] <= 0)) continue;
switch (p_info[i][bAdmin])
{
case 1: ttext = "{33AA33}(Практикант){FFFFFF}";
case 2: ttext = "{33AA33}(Модератор){FFFFFF}";
case 3: ttext = "{33CCFF}(Мл.Администратор){FFFFFF}";
case 4: ttext = "{FF9900}(Администратор){FFFFFF}";
case 5: ttext = "{FF9900}(Ст.Администратор){FFFFFF}";
case 6: ttext = "{D900D3}(Гл.Администратор){FFFFFF}";
case 7: ttext = "{FF0000}(Основатель){FFFFFF}";
}
strcat(stringer, ttext);
strcat(stringer, " ");
strcat(stringer, NamePlayer[i]);
format(stringer1, 256," [lvl: %d] [ID: {9ACD32}%d] %s\n",p_info[i][bAdmin], i, (p_info[i][pAFK]) > 3 ? ("{ffff00}[AFK]"cWHITE"") : (""));
strcat(stringer, stringer1);
}
ShowPlayerDialog(playerid, 999, DIALOG_STYLE_MSGBOX, "Администрация в сети:", stringer, "Закрыть", "");
return 1;
}
Тут обнуляет переменную если не ошибаюсь,а для чего?без этого никак не обойдется? объясните если не лень
Re: переменная -
eakwarp - 13.08.2016
Прост.
Re: переменная -
Diman777 - 13.08.2016
Потому что если этого не сделать, то при следующем обращении к глобальной переменной - старый текст в ней останится.
Re: переменная -
DrSlett - 13.08.2016
dele
Re: переменная -
Diman777 - 13.08.2016
Quote:
Originally Posted by DrSlett
В данном коде - нет.
|
В смысле? Что нет?
Re: переменная -
ZiGGi - 13.08.2016
Quote:
Originally Posted by Diman777
Потому что если этого не сделать, то при следующем обращении к глобальной переменной - старый текст в ней останится.
|
Не правда, в Pawn все переменные по умолчанию инициализируются нулями. А значение переменной после предыдущего вызова может остаться только в случае объявления её в качестве
static.
Re: переменная -
eakwarp - 13.08.2016
А, это тот случай, когда ради мнимой оптимизации вывели строковую переменную в глобал и теперь вынуждены ее очищать при каждом использовании.
Re: переменная -
FaGo - 13.08.2016
Quote:
Originally Posted by Diman777
Потому что если этого не сделать, то при следующем обращении к глобальной переменной - старый текст в ней останится.
|
Quote:
Originally Posted by ZiGGi
Не правда, в Pawn все переменные по умолчанию инициализируются нулями. А значение переменной после предыдущего вызова может остаться только в случае объявления её в качестве static.
|
Спасибо за ответы +
Re: переменная -
Diman777 - 13.08.2016
Quote:
Originally Posted by ZiGGi
А значение переменной после предыдущего вызова может остаться только в случае объявления её в качестве static.
|
Ты уверен?)
PHP код:
new global_int;
new global_str[4+1];
TestFunc()
{
printf("global_int = %d, global_str = '%s'", global_int, global_str);
}
public OnGameModeInit()
{
TestFunc();
global_int = 44;
global_str = "тест";
TestFunc();
return 1;
}
//Консоль:
//[23:12:39] global_int = 0, global_string = ''
//[23:12:39] global_int = 44, global_string = 'тест'
Quote:
Originally Posted by FaGo
тупо осмотреться и узнать кое-что новое
|
Ты узнал как не правильно делать. Такие данные как вывод текущего списка админов со всякими статусами - так не делается. Нужно сначала работать с переменной (отдельно), а при вызове команды - показывать игроку уже
подготовленную строку для вывода в диалог. А в приведённом коде при вызове команды сразу всё делается (foreach, strcat и другие вещи).
Re: переменная -
ZiGGi - 13.08.2016
Quote:
Originally Posted by eakwarp
А, это тот случай, когда ради мнимой оптимизации вывели строковую переменную в глобал и теперь вынуждены ее очищать при каждом использовании.
|
Quote:
Originally Posted by Diman777
Ты уверен?)
|
Не заметил 1 в конце переменной и подумал, что stringer был объявлен внутри функции, а там, оказывается, stringer1. А с таким подходом к именованию переменных - это не удивительно. Так что мои слова относятся только к локальным переменным и да, если она глобальная, то её, конечно, нужно очищать.
Кстати, это как-раз один из тех случаев, когда человек с целью оптимизации делает только хуже, причём как и по памяти, так и по производительности.
Re: переменная -
ZiGGi - 13.08.2016
Примерно так должен выглядеть хорошо оптимизированый код этой команды:
PHP код:
#define MAX_ADMIN_LEVEL_NAME_STRINGS 34
static const
gAdminLevelNameStrings[][MAX_ADMIN_LEVEL_NAME_STRINGS char] = {
!"{33AA33}(Практикант){FFFFFF}",
!"{33AA33}(Модератор){FFFFFF}",
!"{33CCFF}(Мл.Администратор){FFFFFF}",
!"{FF9900}(Администратор){FFFFFF}",
!"{FF9900}(Ст.Администратор){FFFFFF}",
!"{D900D3}(Гл.Администратор){FFFFFF}",
!"{FF0000}(Основатель){FFFFFF}"
};
stock GetAdminLevelNameString(admin_level, name[], const size = sizeof(name))
{
if (!(1 < admin_level < sizeof(gAdminLevelNameStrings))) {
return 0;
}
return strunpack(name, gAdminLevelNameStrings[admin_level - 1], size);
}
CMD:admins(playerid, params[])
{
new
level_name[MAX_ADMIN_LEVEL_NAME_STRINGS];
foreach (new i : Player) {
if (p_info[i][bAdmin] <= 0) {
continue;
}
GetAdminLevelNameString(p_info[i][bAdmin], level_name);
format(stringer, sizeof(stringer),
"%s%s %s [lvl: %d] [ID: {9ACD32}%d] %s\n",
stringer,
level_name,
NamePlayer[i]
p_info[i][bAdmin],
i,
p_info[i][pAFK] > 3 ? "{ffff00}[AFK]"cWHITE : "");
}
ShowPlayerDialog(playerid, 999, DIALOG_STYLE_MSGBOX, "Администрация в сети:", stringer, "Закрыть", "");
return 1;
}
В идеале, конечно, для foreach лучше добавить новый интервал, и помещать в этот интервал только администраторов, тогда лишних тиков в цикле не станет.
Re: переменная -
Diman777 - 13.08.2016
Quote:
Originally Posted by ZiGGi
А с таким подходом к именованию переменных - это не удивительно.
|
Естественно, нормальные программисты так не делают.
Quote:
Originally Posted by ZiGGi
Это как-раз один из тех случаев, когда человек с целью оптимизации делает только хуже, причём как и по памяти, так и по производительности.
|
Я в своё время посмотрел не малое кол-во модов и такого рода кода довольно много.
Это печально - потому что новичок так и будет делать как в этих модах. А изучать язык - никто не хочет, всем надо готовое, вот и получаем результат.
Зигги ты понимаешь, что на такие вещи всё равно уходит время?
PHP код:
new
level_name[ sizeof(gAdminLevelNames[]) ];
foreach (new i : Player) {
if (p_info[i][bAdmin] <= 0) {
continue;
}
GetAdminLevelName(p_info[i][bAdmin], level_name);
format(stringer, sizeof(stringer),
"%s%s %s [lvl: %d] [ID: {9ACD32}%d] %s\n",
stringer,
level_name,
NamePlayer[i]
p_info[i][bAdmin],
i,
p_info[i][pAFK] > 3 ? "{ffff00}[AFK]"cWHITE : "");
}
Как вариант - вот этот участок кода обрабатывать нужно где-то в
другом месте, я имею ввиду не в команде.
=> при вызове команды показываем уже готовый список
stringer:
PHP код:
CMD:admins(playerid, params[])
{
ShowPlayerDialog(playerid, 999, DIALOG_STYLE_MSGBOX, "Администрация в сети:", stringer, "Закрыть", "");
return 1;
}
Re: переменная -
Profyan - 16.08.2016
В чем недостатки использования глобальных массивов,как строку для форматирования, кроме как ее очищения,если не используешь формат? AMX машина ведь однопоточна и проблем возникнуть с этим не должно?!
Re: переменная -
gensek4 - 18.08.2016
Quote:
Originally Posted by ZiGGi
Примерно так должен выглядеть хорошо оптимизированый код этой команды:
PHP код:
#define MAX_ADMIN_LEVEL_NAME_STRINGS 34
static const
gAdminLevelNameStrings[][MAX_ADMIN_LEVEL_NAME_STRINGS char] = {
!"{33AA33}(Практикант){FFFFFF}",
!"{33AA33}(Модератор){FFFFFF}",
!"{33CCFF}(Мл.Администратор){FFFFFF}",
!"{FF9900}(Администратор){FFFFFF}",
!"{FF9900}(Ст.Администратор){FFFFFF}",
!"{D900D3}(Гл.Администратор){FFFFFF}",
!"{FF0000}(Основатель){FFFFFF}"
};
stock GetAdminLevelNameString(admin_level, name[], const size = sizeof(name))
{
if (!(1 < admin_level < sizeof(gAdminLevelNameStrings))) {
return 0;
}
return strunpack(name, gAdminLevelNameStrings[admin_level - 1], size);
}
CMD:admins(playerid, params[])
{
new
level_name[MAX_ADMIN_LEVEL_NAME_STRINGS];
foreach (new i : Player) {
if (p_info[i][bAdmin] <= 0) {
continue;
}
GetAdminLevelNameString(p_info[i][bAdmin], level_name);
format(stringer, sizeof(stringer),
"%s%s %s [lvl: %d] [ID: {9ACD32}%d] %s\n",
stringer,
level_name,
NamePlayer[i]
p_info[i][bAdmin],
i,
p_info[i][pAFK] > 3 ? "{ffff00}[AFK]"cWHITE : "");
}
ShowPlayerDialog(playerid, 999, DIALOG_STYLE_MSGBOX, "Администрация в сети:", stringer, "Закрыть", "");
return 1;
}
В идеале, конечно, для foreach лучше добавить новый интервал, и помещать в этот интервал только администраторов, тогда лишних тиков в цикле не станет.
|
А в чем прикол возится с запакованными строками, когда можно сразу создать массив -
PHP код:
static const GetPlayerAdminName[4][15] = {"Практикант", "Модератор", "Администратор", "Основатель"};
И работать с ним напрямую повсеместно. И не нужно все время создавать переменные, что бы распаковать нужную переменную. (это я ввиду к тому, что если это использовать для обозначение рангов везде, а не в одном месте).
Re: переменная -
ZiGGi - 18.08.2016
Quote:
Originally Posted by gensek4
А в чем прикол возится с запакованными строками, когда можно сразу создать массив -
PHP код:
static const GetPlayerAdminName[4][15] = {"Практикант", "Модератор", "Администратор", "Основатель"};
И работать с ним напрямую повсеместно. И не нужно все время создавать переменные, что бы распаковать нужную переменную. (это я ввиду к тому, что если это использовать для обозначение рангов везде, а не в одном месте).
|
Я предпочитаю ограничивать область видимости глобальных переменных в пределах одного файла (static) и создавать "публичные" функции для работы с ними. Некоторое подражание сеттерам и геттерам в ООП.
Re: переменная -
eakwarp - 19.08.2016
Quote:
Originally Posted by Profyan
В чем недостатки использования глобальных массивов,как строку для форматирования, кроме как ее очищения,если не используешь формат? AMX машина ведь однопоточна и проблем возникнуть с этим не должно?!
|
Зачем? Массивы внутри функций не занимают стек, это действия ради действия не являющееся чем-то логичным, или оптимизацией.
Re: переменная -
gensek4 - 20.08.2016
Quote:
Originally Posted by eakwarp
Зачем? Массивы внутри функций не занимают стек, это действия ради действия не являющееся чем-то логичным, или оптимизацией.
|
Как это не занимают? Откуда ты взял эту информацию? Использование множества локальных переменных как раз и приводят к переполнению стека. Использование одной глобальной (или несколько) глобальных решают эту проблему. Если грамотно использовать почему бы и нет, проблем с этим не будет.
Re: переменная -
eakwarp - 22.08.2016
Quote:
Originally Posted by gensek4
Как это не занимают? Откуда ты взял эту информацию? Использование множества локальных переменных как раз и приводят к переполнению стека. Использование одной глобальной (или несколько) глобальных решают эту проблему. Если грамотно использовать почему бы и нет, проблем с этим не будет.
|
Нет.
Re: переменная -
stabker - 22.08.2016
Quote:
Originally Posted by eakwarp
...Массивы внутри функций не занимают стек...
|
PHP код:
main()
{
printf("heapspace: %d", heapspace());
new array[100];
printf("heapspace: %d", heapspace());
}
??7
Re: переменная -
Stepashka - 22.08.2016
Quote:
Originally Posted by stabker
PHP код:
main()
{
printf("heapspace: %d", heapspace());
new array[100];
printf("heapspace: %d", heapspace());
}
??7
|
Ваша функция всё ещё жива, так же как и переменная, проверять надо после выполнения функции.