PDA

Просмотр полной версии : [Урок] Операторы в Pawn



Seregamil
09.12.2013, 03:33
Добрый день пользователи портала
Тема уже сотая с данным содержимым, но дельных тем я так и не увидел

Для любителей википедии, а не текста, приведенного ниже посвящается: http://wiki.sa-mp.com/wiki/Control_Structures#Operators

Начну пожалуй с всеми любимого
if/else


if с англ = если



new local = 4;//создадим глобальную переменную local
main(){
if(local == 4) print("okay");//если эта переменная будет равна четырем = все окей
else if(local == 2) print("local = 2");//если равна двум оповестим об этом в лог
else printf("local = %d",local);//если неподходит под значения, приведенные выше = выведем в лог значение переменной
}

Это достаточно веселенькая конструкция, но в ней иногда можно запутаться =)
По поводу операторов, используемых в условиях:

Оператор && - и



new local = 15, shot = 3;

main(){
if(local == 15 && shot == 3){
print("Все очень даже хорошо");
}
}

Пример не очень, но думаю понятно, если условие == тому то, и другое условие == тому то, то происходит то то

Оператор || - или


new okay = 1, local = 423;

main(){
if(okay == 2 || local == 423){
print("okay");
}
}

Если любое из условий истинно, то конструкция сработает

Оператор ! - не



public OnPlayerSpawn(playerid){
if(!IsPlayerInRangeOfPoint(playerid,3.0,0.0,0.0,0.0)){//если игрок Не находится в радиусе 3-х метров у позиции с нулями
print("ok");
}
return true;
}



Про операторы сравнения (> < => =<) я думаю объяснять не стоит

Перейдем к конструкции
switch

Думаю про нее все наслышаны, поэтому покажу лишь пример использования



switch(GetPlayerScore(playerid)){
case 10: SendClientMessage(playerid,-1,"10 фрагов");
case 20: SendClientMessage(playerid,-1,"20 фрагов");
case 30: SendClientMessage(playerid,-1,"30 фрагов");
default: SendClientMessage(playerid,-1,"Чото не то");
}


case ...: - условие, подобно if
default: - не подходит ни к одному из вышеперечисленных условий

Конструкция
?:
Или же "тернарный оператор"

Данная конструкция схожа с if/else, но выглядит она в виде однострочного решения

Общий вид конструкции:


логическое выражение ? выражение 1 : выражение 2

Простое применение:



SetPlayerHealth(playerid, (IsPlayerAdmin(playerid) ? 100.0 : 50.0));//если игрок в рконе - установим ему 100 хр, в противном случае - 50 хр



new
a,
b = 3;
if (b == 1)
{
a = 2;
}
else if (b == 2)
{
a = 3;
}
else if (b == 3)
{
a = 4;
}
else
{
a = 5;
}


//Будет равносильно

new
a,
b = 3;
a = (b == 1) ? (2) : ((b == 2) ? (3) : ((b == 3) ? (4) : (5)));



И т.д.


Далее перейдем к циклам


while

Использование:




new local = 0;

while(local != 10){
//ваши задачи для цикла
local++;//увеличим переменную local
}


Цикл вида
for имеют вид



for(переменные; переменные != нужному вам числу и прочему прочему; что с этими переменными делать будете)


Приведу пример на валидность пароля


valid_password(password[]){
for(new i;i!=strlen(password);i++){//пробежимся по всей строке
switch(password[i]){//проверим символ номера i
case 'A'..'Z','a'..'z','0'..'9': continue;//если символ верхнего регистра, или нижнего, все это инглиш буковками, или там цифра - не будем кричать
default: return false;//но если символ неподошел под условия свыше - пароль неверный
}
}
return true;//сообщим, что пароль верный
}


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

break обрывает цикл, проще говоря


for(new j;j!=10;j++){
if(j == 5) break;//если значение в переменной равно 5 - оборвем цикл
}



Теперь стартуем к моей самой любимой проблеме -
return

return может возвращать числовые, дробные, текстовые значения, вызывать различного рода функции

Примеры:
Текстовые значения - проверка на присутствие игрока на сервере и вывод текста "В сети/Не в сети":

connected_user(nick[]){
new str[50];
format(str,50,"{ff0000}Не в сети");
for(new i;i!=GetMaxPlayers();i++){//запустим цикл по всем игрокам
if(IsPlayerNPC(i) || !IsPlayerConnected(i)) continue;//если игрок бот или вообще не в сети - пропустим действие
if(strcmp(p_name(i), nick, true)==0){//если на сервере имя игрока и имя, которое мы ищем, совпали
format(str,50,"{00ff00}В сети");//значит игрок в сети
break;//оборвем цикл
}
}
return str;//и вернем текст
}

p_name(playerid){
new name[24];
GetPlayerName(playerid,name,24);
return name;
}


Числовые значения:
Узнать кол-во патронов в слоте

getAmmoGun(playerid,id){
for(new i,gun,ammo;i!=13;i++){//запустим цикл по всем слотам оружия
GetPlayerWeaponData(playerid,i,gun,ammo);//получим данные в слоте
if(gun == id){//если ID оружия совпали
return ammo;//вернем патроны у этого оружия
}
}
return -1;//если же ничего ненайдет - отправит -1
}

Автор: Seregamil

Osetin
13.12.2013, 23:19
Почистил тему!

Salvacore
14.12.2013, 23:00
Молодец.

TWIX
15.12.2013, 12:17
Как всегда радуешь..

.::Riki::.
26.12.2013, 10:10
новечкам полезно

Unreal
08.10.2015, 17:36
for(new i;i!=strlen(password);i++){//пробежимся по всей строке

будет ли разница если я сделаю допустим так ?

for(new i, _str = strlen(password);i!=_str;i++)

MacMailler
10.10.2015, 06:47
будет ли разница если я сделаю допустим так ?

for(new i, _str = strlen(password);i!=_str;i++)

Будет

Desulaid
10.10.2015, 07:14
Будет

А я не уверен



for(new i; i != strlen(password); i++)

for(new i, str = strlen(password); i!= _str; i++)

Unreal
10.10.2015, 15:51
А я не уверен



for(new i; i != strlen(password); i++)

for(new i, str = strlen(password); i!= _str; i++)


теперь смотри, я приведу в ответ другой пример:

for(new i = 0; i <= GetPlayerPoolSize(); i++)
и

for(new i = 0,poolsize = GetPlayerPoolSize(); i <= poolsize; i++)

Desulaid
10.10.2015, 19:39
теперь смотри, я приведу в ответ другой пример:

for(new i = 0; i <= GetPlayerPoolSize(); i++)
и

for(new i = 0,poolsize = GetPlayerPoolSize(); i <= poolsize; i++)

Опять такой разницы не вижу, хотя могу и ошибаться.



for(new i = 0; i <= GetPlayerPoolSize(); i++)

for(объявили обнуленную переменную; если переменная меньше/равна количеству игроков; инкрементировали переменную)


for(new i = 0,poolsize = GetPlayerPoolSize(); i <= poolsize; i++)

for(объявили обнуленную переменную; получили число игроков и сохранили в другой переменной; если переменная меньше количества в другой переменной; инкрементировали первую переменную)


Ну как то так :)

Daniel_Cortez
10.10.2015, 20:10
Опять такой разницы не вижу, хотя могу и ошибаться.



for(new i = 0; i <= GetPlayerPoolSize(); i++)

for(объявили обнуленную переменную; если переменная меньше/равна количеству игроков; инкрементировали переменную)


for(new i = 0,poolsize = GetPlayerPoolSize(); i <= poolsize; i++)

for(объявили обнуленную переменную; получили число игроков и сохранили в другой переменной; если переменная меньше количества в другой переменной; инкрементировали первую переменную)


Ну как то так :)
В первом варианте значение GetPlayerPoolSize() не кэшируется перед началом цикла, а значит, эта функция будет снова вызываться после каждой итерации.