Текущая версия SA-MP: 0.3.7


IP: 77.220.180.96:7777
  Новые сообщения · Поиск
  • Страница 1 из 1
  • 1
Модератор форума: KaTacTpOqpa  
Циклы в Pawno
BJIADOKC Сообщение # 1  | 20:09:23
Скриптеры
Сообщений: 601
Репутация: 161
Как мы все прекрасно видим, уроков реально по скриптингу мало, а также я заметил, что некоторые не умеют обращаться с циклами. О том, что многие здесь даже не ведают об операторах continue и break, я вообще промолчу. Думаю, данный урок будет им полезен. Постарался изложить все доступным языком.
Сперва узнаем - что же такое цикл?
Цикл - это конструкция, позволяющая выполнить определенное действие n-ное количество раз.
Циклы могут избавить программиста от очень муторной работы. Сравним коды, выполняющие одинаковую задачу:
Code

SendClientMessage(playerid, 0xFFFFFFFF, "");
SendClientMessage(playerid, 0xFFFFFFFF, "");
SendClientMessage(playerid, 0xFFFFFFFF, "");
SendClientMessage(playerid, 0xFFFFFFFF, "");
SendClientMessage(playerid, 0xFFFFFFFF, "");
SendClientMessage(playerid, 0xFFFFFFFF, "");
SendClientMessage(playerid, 0xFFFFFFFF, "");
SendClientMessage(playerid, 0xFFFFFFFF, "");
SendClientMessage(playerid, 0xFFFFFFFF, "");     


Code

new a;
while(a++ < 10)
{
SendClientMessage(playerid, 0xFFFFFFFF, "");
}     

Какой вариант лучше? Думаю, очевидно, что второй.
Циклы в Pawn бывают четырех видов:

* while
* for
* do..while
* switch..case

1. Цикл while.
Цикл while выполняет действие, пока указанное условие является истинным. Конструкция цикла:
Code

while(условие)
{
инструкции (говоря проще, операции)
}     

То, что расположено внутри фигурных скобок, называется телом цикла.
Пример цикла:
Code

new a; //Объявляем переменную a
while(a < 10)
{
printf("%d", 10);
a ++;
}     

В результате цикл выведет в консоль числа от 1 до 10.
Этот код еще можно сократить. В результате мы получим:
Code

new a; //Объявляем переменную a
while(a++ < 10)
{
printf("%d", a);
}     

2. Цикл for.
Это, по сути, упрощенный цикл while. Его можно использовать, к примеру, для проверки данных всех игроков. Заменить пример цикла while, который я писал выше, циклом for, можно так:
Code

for(new a; a < 10; a++)
{
printf("%d", a);
}     


Конструкция:
Code

for(переменные; условие; операция с переменной-счетчиком)
{
инструкции
}     

3. Цикл do..while.
Цикл do..while похож на цикл while, но есть отличие. В чем же, спросите вы, оно заключается? А в том, что сначала выполняются инструкции, а потом проверяется условие. В цикле while все с точностью до наоборот. Конструкция цикла:
Code

do
{
инструкции
}
while(условие);     

Опять же, пример скрипта, выводящего в консоль цифры:
Code

new a;
do
{
printf("%d", a);
a ++;
}
while(a < 10);     

Первое число выведет вне зависимости от того, меньше ли оно десяти. То есть, если a будет равно, скажем, 17, в консоль это число все равно выведет, но остальные - нет.
4. Цикл switch..case.
Цикл switch..case перебирает значения указанной переменной. Конструкция цикла:
Code

switch(переменная)
{
case значение:
{
инструкции
}
case второе_значение:
{
инструкции
}
default: //Если значение переменной не равно ни одному (из тех, что в case)
{
инструкции
}     

Пример цикла:
Code

new a = 12;
switch(a)
{
case 3:
{
print("a = 3");
}
case 7:
{
print("a = 7");
}
case 12:
{
print("a = 12");
}
default:
{
print("a не равняется ни одному из значений");
}
}     

Также в цикле такого вида можно указывать диапазон значений. Диапазон указывается точками. К примеру:
Code

new a = 12;
switch(a)
{
case 3:
{
print("a = 3");
}
case 7:
{
print("a = 7");
}
case 9..15: //Если значение переменной a от 9 до 15
{
print("a = 12");
}
default:
{
print("a не равняется ни одному из значений");
}
}     

То есть (в третьем кейсе), если значение a от 9 до 15, как и в первом примере, в консоль выведет: "a = 12". Также в одном кейсе можно указывать несколько значений. Пример:
Code

new a = 12;
switch(a)
{
case 7, 12, 18: //Если a равно 7, 12 или 18
{
print("a = 7 || a = 12 || a = 18");
}
case 5..10, 16..18: //Если значение a от 5 до 10, либо от 16 до 18
{
print("a = 5 || a = 6 || a = 7 || a = 8 || a = 9 || a = 10 || a = 16 || a = 17 || a = 18");
}
}     

В кейсах может быть и проверка на символы. Они заключаются в одиночные скобки.
5. Операторы для работы с циклами.
Для работы с циклами есть два специальных оператора - continue и break. Сейчас разберемся, как они работают.
5.1. Оператор continue.
Допустим, у нас выполняются действия, и вдруг появляется необходимость переключить цикл на следующую итерацию. Что же в таком случае нужно делать? Использовать оператор continue. Этот оператор пропускает оставшееся действие текущей итерации, мгновенно переключая на следующую. Посмотрим, как его использовать, на примере. Предположим, у нас под таймером стоит цикл на всех игроков, где идут различные проверки, но тут (в одной из итераций) игрока нужно кикнуть. Цикл, вне зависимости от того, кикнут или не кикнут игрок, продолжит выполнение текущей итерации. Возьмем для этого цикл for:
Code

for(new a; a < 50; a++) //Проверяем первые 50 игроков
{
if(GetPlayerSpecialAction(a) == 2) Kick(a);
new b;
b ++;
}     

В этом случае после кика переменная b все равно увеличится на 1 (повторяю, это только пример. Инструкций может быть гораздо больше). А в этом примере экономится время и сразу после кика выполняется переход к следующей итеграции:
Code

for(new a; a < 50; a++) //Проверяем первые 50 игроков
{
if(GetPlayerSpecialAction(a) == 2)
{
Kick(a);
continue;
}
new b;
b ++;
}     

То есть здесь после кика к переменной b значение 1 уже не прибавится, а будет проверять уже следующего игрока.
5.2. Оператор break.
Допустим, у нас есть бесконечный цикл (немного о них можно почитать в п. 6), и нужно выйти из цикла до его "естественного" окончания. Для этого моно использовать оператор break.
Оператор break завершает цикл до окончания выполнения всех инструкций. Допустим, у нас, опять же, есть цикл на проверку пятидесяти игроков. Если значение денег десятого игрока равно $100, мы остальных игроков не проверяем (то есть завершаем цикл):
Code

for(new a; a < 50; a++)
{
if(a == 10)
{
if(GetPlayerMoney(a) == 100) //Если у игрока под ID 10 100 долларов
{
break; //Завершаем действие цикла
}
}
}     

6. Бесконечные циклы.
Циклы, конечно же, могут выполняться бесконечно. Легче всего делать бесконечные циклы, используя конструкцию for. Выглядеть это будет так:
Code

for(условия)
{
инструкции
}     


7. конструкция if

условие if
содержит 5 знаков условий:
Code

== - равно
!= - не равно
>= больше или равно
<= меньше или равно
?= приблизительно равно (например 143.666666666 приблизительно равно 144)

и разграничители
Code

&& - и (если ... и ... то ...)
|| - или (если ... или ... то ...)
& - обычно используется только в OnPlayerKeyStateChange, не имеет особого отличия от ==

также можно ставить дополнительные скобки для группировки функций
например
Code

if((IsPlayerAdmin(playerid) && IsPlayerConnected(playerid)) || (!IsPlayerAdmin(playerid) && !IsPlayerConnected(playerid)))

поясню сразу ретурны после if
некоторые люди спрашивают "зачем после условия ставить ретурн с функцией?" поясняю:
если поставить так:
if(...)
{
Function();
}
то функция выполнится, но остальной код тоже выполнится
если поставить так:
if(...)
{
Function();
return 1(0);
}
это будет то же самое что и ретурн после ифа, только больше строк займет
!!! ретурн после ифа нужен для того чтобы завершить всю функцию (конечный результат стоит после ретурна)
например в комманде бан:
Code

if(!IsPlayerAdmin(playerid)) return SendClientMessage(playerid,0xFF0000AA,"Ты не администратор");

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


тут больше не сижу... открыл свой проект
[EL]SlayeR Сообщение # 2  | 01:34:40
Пользователи
Сообщений: 3
Репутация: 1
Как вы такие умные)))???!!! biggrin biggrin biggrin я тоже таким хачю быть))) tongue но жаль что я не могу понять павн((( sad очень хачю на учится но не получяется я умею всеголиш машины и сапвн раставлять и все ((( sad sad sad
Demetrius Сообщение # 3  | 16:56:41
VIP-пользователи
Сообщений: 1192
Репутация: 158
прочитай внимательно как создать ТДМ и ДМ сервера, это азы так сказать
зы: все далай на практике, а то и правда ничего не поймешь


Sweet >>> Armin >>> Demetrius

SA:MP >> MTA:SA >> IRL
DIZ_man Сообщение # 4  | 20:24:59
Пользователи
Сообщений: 27
Репутация: 0
Урок понятный и удобный!


Demetrius Сообщение # 5  | 12:11:37
VIP-пользователи
Сообщений: 1192
Репутация: 158
Quote (BJIADOKC)
поясню сразу ретурны после if
некоторые люди спрашивают "зачем после условия ставить ретурн с функцией?" поясняю:
если поставить так:
if(...)
{
Function();
}
то функция выполнится, но остальной код тоже выполнится
если поставить так:
if(...)
{
Function();
return 1(0);
}
это будет то же самое что и ретурн после ифа, только больше строк займет

вот в с++ return 1 возвращает ос о том что все функции выполнились, return 0 об ошибке
какая разница между ними в павно?


Sweet >>> Armin >>> Demetrius

SA:MP >> MTA:SA >> IRL
BJIADOKC Сообщение # 6  | 13:08:07
Скриптеры
Сообщений: 601
Репутация: 161
Quote (Armin)
вот в с++ return 1 возвращает ос о том что все функции выполнились, return 0 об ошибке
какая разница между ними в павно?

return 1; завершает поток (в котором стоит ретурн)
return 0; завершает действие всего паблика до его следующего вызова


тут больше не сижу... открыл свой проект
Demetrius Сообщение # 7  | 23:44:05
VIP-пользователи
Сообщений: 1192
Репутация: 158
Quote (BJIADOKC)
return 1; завершает поток (в котором стоит ретурн)
return 0; завершает действие всего паблика до его следующего вызова

спс)

Добавлено (01.06.2011, 23:44)
---------------------------------------------

Quote (BJIADOKC)
Циклы, конечно же, могут выполняться бесконечно. Легче всего делать бесконечные циклы, используя конструкцию for

бесконечный цикл запускается без указания условия up
а и еще
Источник
smile


Sweet >>> Armin >>> Demetrius

SA:MP >> MTA:SA >> IRL
BJIADOKC Сообщение # 8  | 01:57:34
Скриптеры
Сообщений: 601
Репутация: 161
Quote (Armin)
Источник

нубопавно.ру? фу...
я это с самп тим скопипастил biggrin


тут больше не сижу... открыл свой проект
Demetrius Сообщение # 9  | 20:08:14
VIP-пользователи
Сообщений: 1192
Репутация: 158
Quote (BJIADOKC)

нубопавно.ру? фу...

biggrin
Quote (BJIADOKC)
я это с самп тим скопипастил

омг smile


Sweet >>> Armin >>> Demetrius

SA:MP >> MTA:SA >> IRL
XocTeP Сообщение # 10  | 23:36:53
Пользователи
Сообщений: 122
Репутация: 0
Неплохо smile

Тут больше не сижу. Открыл свой проект.
XocTeP Сообщение # 11  | 11:20:46
Пользователи
Сообщений: 122
Репутация: 0
lol

Тут больше не сижу. Открыл свой проект.
SoNik)) Сообщение # 12  | 13:05:26
Редактор
Сообщений: 131
Репутация: 137
Цитата (вверху)
Опять набивание постов... ЗОБАНЬИТЕ ИГО НОВСЕГДА!1111!!!1!!11

Хотя-бы отнять у него парочку постов)
в личной инфе
[JIuC]eH[oK] Сообщение # 13  | 16:17:19
Модераторы
Сообщений: 972
Репутация: 414
Цитата (SoNik)))
Хотя-бы отнять у него парочку постов)
в личной инфе

Уже сделал...)))


Администратор Универсала.
По вопросам обращайтесь ко мне в
Личку.
SoNik)) Сообщение # 14  | 00:31:24
Редактор
Сообщений: 131
Репутация: 137
А мне прибавить репу ?? хДД
[JIuC]eH[oK] Сообщение # 15  | 14:05:27
Модераторы
Сообщений: 972
Репутация: 414
Цитата (SoNik)))
А мне прибавить репу ?? хДД

Убавить? xD


Администратор Универсала.
По вопросам обращайтесь ко мне в
Личку.
SoNik)) Сообщение # 16  | 14:54:57
Редактор
Сообщений: 131
Репутация: 137
Цитата (|JIuC|eH|oK|)
Убавить? xD

teehee
  • Страница 1 из 1
  • 1
Поиск: