переменная
#1

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

PHP код:
CMD:admins(playeridparams[])
{
    new 
ttext[35], stringer1[500];
    
stringer "";
    foreach(new 
Player)
    {
        if (!
IsPlayerConnected(i) || IsPlayerNPC(i) || (p_info[i][bAdmin] <= 0)) continue;
        switch (
p_info[i][bAdmin])
        {
            case 
1ttext "{33AA33}(Практикант){FFFFFF}";
            case 
2ttext "{33AA33}(Модератор){FFFFFF}";
            case 
3ttext "{33CCFF}(Мл.Администратор){FFFFFF}";
            case 
4ttext "{FF9900}(Администратор){FFFFFF}";
            case 
5ttext "{FF9900}(Ст.Администратор){FFFFFF}";
            case 
6ttext "{D900D3}(Гл.Администратор){FFFFFF}";
            case 
7ttext "{FF0000}(Основатель){FFFFFF}";
        }
        
strcat(stringerttext);
        
strcat(stringer" ");
        
strcat(stringerNamePlayer[i]);
        
format(stringer1256," [lvl: %d] [ID: {9ACD32}%d] %s\n",p_info[i][bAdmin], i, (p_info[i][pAFK]) > ? ("{ffff00}[AFK]"cWHITE"") : (""));
        
strcat(stringerstringer1);
    }
    
ShowPlayerDialog(playerid999DIALOG_STYLE_MSGBOX"Администрация в сети:"stringer"Закрыть""");
    return 
1;


Тут обнуляет переменную если не ошибаюсь,а для чего?без этого никак не обойдется? объясните если не лень

PHP код:
stringer ""
Reply
#2

Прост.
Reply
#3

Потому что если этого не сделать, то при следующем обращении к глобальной переменной - старый текст в ней останится.
Reply
#4

dele
Reply
#5

Quote:
Originally Posted by DrSlett
Посмотреть сообщение
В данном коде - нет.
В смысле? Что нет?
Reply
#6

Quote:
Originally Posted by Diman777
Посмотреть сообщение
Потому что если этого не сделать, то при следующем обращении к глобальной переменной - старый текст в ней останится.
Не правда, в Pawn все переменные по умолчанию инициализируются нулями. А значение переменной после предыдущего вызова может остаться только в случае объявления её в качестве static.
Reply
#7

А, это тот случай, когда ради мнимой оптимизации вывели строковую переменную в глобал и теперь вынуждены ее очищать при каждом использовании.
Reply
#8

Quote:
Originally Posted by Diman777
Посмотреть сообщение
Потому что если этого не сделать, то при следующем обращении к глобальной переменной - старый текст в ней останится.
Quote:
Originally Posted by ZiGGi
Посмотреть сообщение
Не правда, в Pawn все переменные по умолчанию инициализируются нулями. А значение переменной после предыдущего вызова может остаться только в случае объявления её в качестве static.
Спасибо за ответы +
Reply
#9

Quote:
Originally Posted by ZiGGi
Посмотреть сообщение
А значение переменной после предыдущего вызова может остаться только в случае объявления её в качестве static.
Ты уверен?)
PHP код:
new global_int;
new 
global_str[4+1];
TestFunc()
{
    
printf("global_int = %d, global_str = '%s'"global_intglobal_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 и другие вещи).
Reply
#10

Quote:
Originally Posted by eakwarp
Посмотреть сообщение
А, это тот случай, когда ради мнимой оптимизации вывели строковую переменную в глобал и теперь вынуждены ее очищать при каждом использовании.
Quote:
Originally Posted by Diman777
Посмотреть сообщение
Ты уверен?)
Не заметил 1 в конце переменной и подумал, что stringer был объявлен внутри функции, а там, оказывается, stringer1. А с таким подходом к именованию переменных - это не удивительно. Так что мои слова относятся только к локальным переменным и да, если она глобальная, то её, конечно, нужно очищать.

Кстати, это как-раз один из тех случаев, когда человек с целью оптимизации делает только хуже, причём как и по памяти, так и по производительности.
Reply
#11

Примерно так должен выглядеть хорошо оптимизированый код этой команды:
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_levelname[], const size sizeof(name))
{
    if (!(
admin_level sizeof(gAdminLevelNameStrings))) {
        return 
0;
    }
    return 
strunpack(namegAdminLevelNameStrings[admin_level 1], size);
}
CMD:admins(playeridparams[])
{
    new
        
level_name[MAX_ADMIN_LEVEL_NAME_STRINGS];
    foreach (new 
Player) {
        if (
p_info[i][bAdmin] <= 0) {
            continue;
        }
        
GetAdminLevelNameString(p_info[i][bAdmin], level_name);
        
format(stringersizeof(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] > "{ffff00}[AFK]"cWHITE "");
    }
    
ShowPlayerDialog(playerid999DIALOG_STYLE_MSGBOX"Администрация в сети:"stringer"Закрыть""");
    return 
1;

В идеале, конечно, для foreach лучше добавить новый интервал, и помещать в этот интервал только администраторов, тогда лишних тиков в цикле не станет.
Reply
#12

Quote:
Originally Posted by ZiGGi
Посмотреть сообщение
А с таким подходом к именованию переменных - это не удивительно.
Естественно, нормальные программисты так не делают.
Quote:
Originally Posted by ZiGGi
Посмотреть сообщение
Это как-раз один из тех случаев, когда человек с целью оптимизации делает только хуже, причём как и по памяти, так и по производительности.
Я в своё время посмотрел не малое кол-во модов и такого рода кода довольно много.
Это печально - потому что новичок так и будет делать как в этих модах. А изучать язык - никто не хочет, всем надо готовое, вот и получаем результат.

Зигги ты понимаешь, что на такие вещи всё равно уходит время?
PHP код:
    new
        
level_namesizeof(gAdminLevelNames[]) ];
    foreach (new 
Player) {
        if (
p_info[i][bAdmin] <= 0) {
            continue;
        }
        
GetAdminLevelName(p_info[i][bAdmin], level_name);
        
format(stringersizeof(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] > "{ffff00}[AFK]"cWHITE "");
    } 
Как вариант - вот этот участок кода обрабатывать нужно где-то в другом месте, я имею ввиду не в команде.
=> при вызове команды показываем уже готовый список stringer:
PHP код:
CMD:admins(playeridparams[])
{
    
ShowPlayerDialog(playerid999DIALOG_STYLE_MSGBOX"Администрация в сети:"stringer"Закрыть""");
    return 
1;

Reply
#13

В чем недостатки использования глобальных массивов,как строку для форматирования, кроме как ее очищения,если не используешь формат? AMX машина ведь однопоточна и проблем возникнуть с этим не должно?!
Reply
#14

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_levelname[], const size sizeof(name))
{
    if (!(
admin_level sizeof(gAdminLevelNameStrings))) {
        return 
0;
    }
    return 
strunpack(namegAdminLevelNameStrings[admin_level 1], size);
}
CMD:admins(playeridparams[])
{
    new
        
level_name[MAX_ADMIN_LEVEL_NAME_STRINGS];
    foreach (new 
Player) {
        if (
p_info[i][bAdmin] <= 0) {
            continue;
        }
        
GetAdminLevelNameString(p_info[i][bAdmin], level_name);
        
format(stringersizeof(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] > "{ffff00}[AFK]"cWHITE "");
    }
    
ShowPlayerDialog(playerid999DIALOG_STYLE_MSGBOX"Администрация в сети:"stringer"Закрыть""");
    return 
1;

В идеале, конечно, для foreach лучше добавить новый интервал, и помещать в этот интервал только администраторов, тогда лишних тиков в цикле не станет.
А в чем прикол возится с запакованными строками, когда можно сразу создать массив -
PHP код:
static const GetPlayerAdminName[4][15] = {"Практикант""Модератор""Администратор""Основатель"}; 
И работать с ним напрямую повсеместно. И не нужно все время создавать переменные, что бы распаковать нужную переменную. (это я ввиду к тому, что если это использовать для обозначение рангов везде, а не в одном месте).
Reply
#15

Quote:
Originally Posted by gensek4
Посмотреть сообщение
А в чем прикол возится с запакованными строками, когда можно сразу создать массив -
PHP код:
static const GetPlayerAdminName[4][15] = {"Практикант""Модератор""Администратор""Основатель"}; 
И работать с ним напрямую повсеместно. И не нужно все время создавать переменные, что бы распаковать нужную переменную. (это я ввиду к тому, что если это использовать для обозначение рангов везде, а не в одном месте).
Я предпочитаю ограничивать область видимости глобальных переменных в пределах одного файла (static) и создавать "публичные" функции для работы с ними. Некоторое подражание сеттерам и геттерам в ООП.
Reply
#16

Quote:
Originally Posted by Profyan
Посмотреть сообщение
В чем недостатки использования глобальных массивов,как строку для форматирования, кроме как ее очищения,если не используешь формат? AMX машина ведь однопоточна и проблем возникнуть с этим не должно?!
Зачем? Массивы внутри функций не занимают стек, это действия ради действия не являющееся чем-то логичным, или оптимизацией.
Reply
#17

Quote:
Originally Posted by eakwarp
Посмотреть сообщение
Зачем? Массивы внутри функций не занимают стек, это действия ради действия не являющееся чем-то логичным, или оптимизацией.
Как это не занимают? Откуда ты взял эту информацию? Использование множества локальных переменных как раз и приводят к переполнению стека. Использование одной глобальной (или несколько) глобальных решают эту проблему. Если грамотно использовать почему бы и нет, проблем с этим не будет.
Reply
#18

Quote:
Originally Posted by gensek4
Посмотреть сообщение
Как это не занимают? Откуда ты взял эту информацию? Использование множества локальных переменных как раз и приводят к переполнению стека. Использование одной глобальной (или несколько) глобальных решают эту проблему. Если грамотно использовать почему бы и нет, проблем с этим не будет.
Нет.
Reply
#19

Quote:
Originally Posted by eakwarp
Посмотреть сообщение
...Массивы внутри функций не занимают стек...
PHP код:
main()
{
    
printf("heapspace: %d"heapspace());
    new array[
100];
    
printf("heapspace: %d"heapspace());



??7
Reply
#20

Quote:
Originally Posted by stabker
Посмотреть сообщение
PHP код:
main()
{
    
printf("heapspace: %d"heapspace());
    new array[
100];
    
printf("heapspace: %d"heapspace());



??7
Ваша функция всё ещё жива, так же как и переменная, проверять надо после выполнения функции.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)