 |
|
 |
|
|
|
Последние Файлы GTA 4 |
Последние Файлы GTA-MP |
Реклама |
|
|
|
|
|
[Урок] Управляющие конструкции Pawn
| |
| _Dark_ | Дата: Вторник, 02.08.2011, 13:00 | Сообщение # 1 |
|
Постоялец
Группа:
I'm V.I.P.
Сообщений: 379
Награды: 4
Город: Dark://core.dll
Репутация: 169
Замечания: 40%
Статус: 
| Добрый всем день. В этой теме я собираюсь рассказать вам о простейших управляющих конструкциях.
Любая программа создается человеком. При этом в нее вкладывается некоторый смысл. А для управления этим смыслом существуют управляющие конструкции. Ведь что такое исполнение программы? Это - пошаговое исполнение, инструкция за инструкцией, кода, написанного программистом.
И вот для управления ходом этого исполнения и нужны конструкции (К слову, они есть не только в Pawn, но и в любом другом языке программирования, различия только в способе применения).
Для начала, расскажу что такое ветвление. Ветвление - способ исполнения кода, при котором в зависимости от определенного условия выполняется определенное действие. В самом деле - нам ведь хочется, что бы программа не выдавала всегда один результат, а выдавала его, основываясь на определенных условиях.
Вот пример: Code if(Key == 1) { SendClientMessage(playerid, COLOR_WHITE, "Переменная 'Key' равна 1!"); } else { SendClientMessage(playerid, COLOR_WHITE, "Переменная 'Key' не равна 1!"); } Прокомментирую: Я думаю, что вы уже знаете что означает переменная и знак == (Никогда не путайте его со знаком = ! Это совершенно разные вещи!) Так вот: ветвление в данном случае - это оператор if. Он проверяет условие(я). Условие - выражение логического типа. Это значит, что оно принимает всего два значения - истина (true / 1), ложь (false / 0). Если результат условия истинный, то выполняется то, что внутри блока if. Если же результат не истинный, то то, что внутри блока if не выполнится. Как же быть, если хочется сделать, что бы при ложном значении выражения выполнилось что-то другое? На помощь приходит необязательный оператор else. Он выполнится, если условие ложно. Но, я повторюсь - он необязательный. Т.е. можно не указывать, что произойдет в случае ложного условия.
Но условный оператор if способен на большее. Мы можем задать сразу несколько условий. Например: Code if(Key == 1) { SendClientMessage(playerid, COLOR_WHITE, "Переменная 'Key' равна 1!"); } else if(Key == 2) { SendClientMessage(playerid, COLOR_WHITE, "Переменная 'Key' равна 2!"); } else if(Key == 3) { SendClientMessage(playerid, COLOR_WHITE, "Переменная 'Key' равна 3!"); } else { SendClientMessage(playerid, COLOR_WHITE, "Я не знаю, чему равна переменная 'Key' =("); } Что мы видим? Мы видим, что в этом случае, даже если переменная 'Key' будет равна 10, то мы все равно увидим результат - сообщение "Я не знаю, чему равна переменная 'Key' =(".
НО: существует еще один полезный но непопулярный (наверно потому что, его не многие знают) оператор ветвления. Это почти что if только он короче и проще. Code new Key=1; new Key2 = Key==1?10:0; printf("%s", Key2); Данный код выведет в консоль 10. И вот почему: При выполнении присваивания выражения ( Key2 = Key) вначале проверится Key==1 и если оно верно, то в переменную попадет, то что после знака ?. Если неверно - то что после знака :
Дополнение от Ghost-X: Данная конструкция может использоваться не только в переменных.
Например, Code stock isInt(var[]) { return ( isNumeric (var) ) ? true : false; }
В данном случае, она используется в функции. Это будет работать следующим образом:
Вы вводите Code new Key[255]="12345"; if(isInt(Key)) { print("Да, это число"); } else print("Нет, я не знаю такого числа!"); . Функция сразу же возвращает Code return ( isNumeric (var) ) ? true : false; ответ. Причем этот ответ узнается в момент возвращения функции true или false, благодаря конструкции которую я описал выше. Функция isNumeric не стандартная, поэтому вот ее код: Code IsNumeric(const string[]) { for (new i = 0, j = strlen(string); i < j; i++) { if (string[i] > '9' || string[i] < '0') return 0; } return 1; }
В примере выше, функция вернет "Да, это число", т.к. в строке содержатся только цифры. Если же мы вместо Key[255]="12345" напишем Key[255]="Hello World" то мы получим ответ "Нет, я не знаю такого числа".
Циклы Цикл - это то же оператор. Он выполняет указанный код указанное количество раз. Начнем с самого простого цикла - for. Code for(new i; i<MAXPLAYERS; i++) { SetPlayerHealth(i, -1); // Убьет всех игроков } Блок кода внутри цикла называется телом цикла. Переменная-счетчик называется итератором цикла, выполнение блока кода циклом - итерацией цикла.
В этом примере: Мы создали переменную i. Задали условие, что оно меньше 500 (MAXPLAYERS по умолчанию равно 500 - лимит игроков). При каждом выполнении цикла, i будет увеличиваться на 1. Таким образом, цикл будет выполняться до тех пор, пока i не станет равным 500. А теперь представьте, что было бы без цикла? Нам бы пришлось делать так: Code SetPlayerHealth(0, -1); SetPlayerHealth(1, -1); SetPlayerHealth(2, -1); ... SetPlayerHealth(500, -1); (Где 0, 1, 2, ... 500 - ID игрока). Согласитесь, не очень то и удобно.
Создавать циклы можно и внутри другого цикла. Code for(new i; i<MAXPLAYERS; i++) { new Float: X, Float: Y, Float: Z; GetPlayerPos(i, X, Y, Z); for(new i2; i2<MAXPLAYERS; i2++) { if(IsPlayerInRangeOfPoint(i2, 20, X, Y, Z)) { SendClientMessage(i2, COLOR_WHITE, "Рядом с вами какой-то другой игрок"); } } } В этом примере, у каждого игрока берется его позиция, а потом у каждого игрока проверяется, находится ли он рядом с каким-нибудь другим игроком. Если да, то ему отправляется сообщение.
Цикл while
Code new Key = 0; while(Key <=50) { print("Key меньше или равно 50!"); Key++; } Цикл будет выполняться, до тех пор пока Key меньше или равно 50. А так как, при каждом выполнении мы увеличиваем Key на 1, то в консоль уйдет 50 сообщений. К слову, если убрать Key++, то цикл будет выполняться бесконечно. Переменная Key никогда не станет равна 50. Так же, если мы создадим переменную Key со значением не 5, а 60, то цикл не выполнится не разу. Этот цикл используют, когда не знают точно, сколько раз его нужно выполнить.
По мимо всего этого, существует оператор break. Он мгновенно прерывает любой цикл. Code new Key = 0; while(Key <=50) { print("Key меньше или равно 50!"); if(Key == 5) break; Key++; } Этот код выведет в консоль 6 сообщений (потому что Key равна 0, а не 1), даже несмотря на то, что в условии цикла сказано другое, потому что, как только Key станет равна 5, произойдет выход из цикла - break.
Так же, существует оператор continue. Он позволяет пропустить выполнение цикла при определенном значении и перейти к следующему выполнению. Например, данный код: Code new Key = 0; while(Key <=20) { Key++; if(Key == 19) continue; printf("%d", Key); } Выведет в консоль числа от 0 до 21, но при этом пропустит число 19, потому что, при каждом выполнении цикла мы проверяем переменную Key, и как только она становится равной 19, мы переходим к следующему шагу цикла, пропуская данное.
Всё, что я хотел сказать по циклам, я сказал. Давайте перейдем к еще одной управляющей конструкции - switch. Она позволяет выполнять то же что и if более простым способом. Code switch(3) { case 0: print("Число 0"); case 1: print("Число 1"); case 2: print("Число 2"); case 3: print("Число 3"); case 4: print("Число 4"); case 5: print("Число 5"); } Данный код выведет в консоль "Число 3". Причем, если бы мы делали тот же самый код с конструкцией if / else, то получилось бы следующее: Code new Key = 3; if(Key ==0) print("Число 0"); else if(Key ==1) print("Число 1"); else if(Key ==2) print("Число 2"); else if(Key ==3) print("Число 3"); else if(Key ==4) print("Число 4"); else if(Key ==5) print("Число 5"); Почти тоже самое, но я бы в данном случае советовал бы использовать switch, не только потому что он удобнее, но и потому что, вроде бы говорят что он быстрее (я никаких замеров не делал). Это что касается if / else. Продолжим разговор о switch. Что же делает эта конструкция? Она перебирает все case до тех пор, пока не найдет значения, совпадающего с указанным в switch(...). Но что делать если она ничего не найдет? В коде выше она просто ничего не выведет, но можно применить кое что еще: Code switch(10) { case 0: print("Число 0"); case 1: print("Число 1"); case 2: print("Число 2"); case 3: print("Число 3"); case 4: print("Число 4"); case 5: print("Число 5"); default: print("Число какое-то другое!"); } Смотрите: данный код выведет в консоль "Число какое-то другое!", потому что мы задали в switch(10) значение, которое не указали в case. Другими словами, применяя default можно указать, что произойдет если не будет найдено ни одного совпадения со значением в case. Тот же код с if/else: Code new Key = 3; if(Key ==0) print("Число 0"); else if(Key ==1) print("Число 1"); else if(Key ==2) print("Число 2"); else if(Key ==3) print("Число 3"); else if(Key ==4) print("Число 4"); else if(Key ==5) print("Число 5"); else print("Число какое-то другое!") . Ну вот и всё, что я хотел вам рассказать в данной теме. Я надеюсь что информация вам будет полезна. Копирайты и все такое: Автор текста, темы, урока - _Dark_ (Если кто-то не в курсе, это я). - При перепечатывании статьи обратная ссылка на данную тему с указанием авторства [blink]обязательна[/blink].
От плюсика не откажусь Если есть вопросы - задавайте. Продолжение следует
Если баги возникают из ниоткуда - ты на правильном пути. (с)
Сообщение отредактировал _Dark_ - Пятница, 05.08.2011, 12:44 |
| |
|
|
| Impereal | Дата: Вторник, 02.08.2011, 14:05 | Сообщение # 2 |
|
Мастер джэдай
Группа:
I'm V.I.P.
Сообщений: 2677
Награды: 51
Город: Санкт-Петербург
| Quote (_Dark_) Данный код выведет в консоль 10. И вот почему: При выполнении присваивания выражения ( Key2 = Key) вначале проверится Key==1 и если оно верно, то в переменную попадет, то что после знака ?. Если неверно, то то что после знака : Вот за это спасибо!
Прощай самп-рус =Р
|
| |
|
|
| Dima-kun | Дата: Вторник, 02.08.2011, 21:46 | Сообщение # 3 |
|
Группа:
Разработчики
Сообщений: 6269
Награды: 72
Репутация: 3512
Замечания: 0%
Статус: 
| Хм. достаточно хорошо расписано.=)
Мои работы: [INC] Сборник d_includes [LAST],[FS] New Demage Effect,[FS]Авто-Поворотники, [FS]mp3player,[FS] Fun Chat Game,[FS] Car Buy Syst,[FS] Anti-AirBrk,[INC] d_setpos, [GM] Game Move v0.1,[FS+include]Super-Armour [0.3z],[FS + Include] Multi Checkpoints
|
| |
|
|
| _Dark_ | Дата: Вторник, 02.08.2011, 22:03 | Сообщение # 4 |
|
Постоялец
Группа:
I'm V.I.P.
Сообщений: 379
Награды: 4
Город: Dark://core.dll
Репутация: 169
Замечания: 40%
Статус: 
| Morino_Reigan, спасибо, стараюсь [off]Завтра выложу урок по функциям.[/off]
Если баги возникают из ниоткуда - ты на правильном пути. (с)
Сообщение отредактировал _Dark_ - Вторник, 02.08.2011, 22:07 |
| |
|
|
| Ghost-X | Дата: Вторник, 02.08.2011, 22:36 | Сообщение # 5 |
|
Мастер джэдай
Группа:
Продвинутые
Сообщений: 3548
Награды: 36
Город: Наб. Челны
Репутация: 856
Замечания: 40%
Статус: 
| Quote (_Dark_) При выполнении присваивания выражения ( Key2 = Key) вначале проверится Key==1 и если оно верно, то в переменную попадет, то что после знака ?. Если неверно - то что после знака : ты забыл про функции. Code stock isInt(var[]) return (isNumeric(var))? true : false; Здесь такой же механизм. Если не ошибаюсь, давно уже подобные конструкции не использовал
Спор на форуме, все равно что олимпиада среди умственно отсталых: даже если ты победил, ты все равно гермофродит. Хочешь остаться при своем мнении - держи его при себе.
|
| |
|
|
| Vantage | Дата: Вторник, 02.08.2011, 23:16 | Сообщение # 6 |
|
Уважаемый человек
Группа:
Пользователи
Сообщений: 974
Награды: 8
Город: -=Los Santos The Best=-
Репутация: 467
Замечания: 80%
Статус: 
| Эх были бы такие мануалы 3 года назад
.. Мои работы: [GM]Ls:Rus TDM v1.0 | [GM]Ls:Rus TDM v1.2 | [GM]Ls:Rus TDM v1.3(1%)[blink]|[/blink] [FS]Rampa
|
| |
|
|
| SLICK | Дата: Среда, 03.08.2011, 00:14 | Сообщение # 7 |
|
Местный
Группа:
I'm V.I.P.
Сообщений: 603
Награды: 9
Город: Unknown
Репутация: 388
Замечания: 0%
Статус: 
| Quote (Foх) Эх были бы такие мануалы 3 года назад
Очень жаль что раньше не было таких статей и приходилось это все самому понимать что да как, если не знаешь основ программирования..
My works: [GM] RTDM Advertising system Fuel System Artefacts Search (Динамическая сис-ма артефактов)
|
| |
|
|
| Vantage | Дата: Среда, 03.08.2011, 00:54 | Сообщение # 8 |
|
Уважаемый человек
Группа:
Пользователи
Сообщений: 974
Награды: 8
Город: -=Los Santos The Best=-
Репутация: 467
Замечания: 80%
Статус: 
| Quote (SLICK) Очень жаль что раньше не было таких статей и приходилось это все самому понимать что да как, если не знаешь основ программирования.. Или вики на инглише разбирать)
.. Мои работы: [GM]Ls:Rus TDM v1.0 | [GM]Ls:Rus TDM v1.2 | [GM]Ls:Rus TDM v1.3(1%)[blink]|[/blink] [FS]Rampa
|
| |
|
|
| Ghost-X | Дата: Среда, 03.08.2011, 09:58 | Сообщение # 9 |
|
Мастер джэдай
Группа:
Продвинутые
Сообщений: 3548
Награды: 36
Город: Наб. Челны
Репутация: 856
Замечания: 40%
Статус: 
| SLICK, эт можно было в любом справочнике прочесть ) По-крайней мере, мы когда изучали все это, ни с кем толком не делились.
Спор на форуме, все равно что олимпиада среди умственно отсталых: даже если ты победил, ты все равно гермофродит. Хочешь остаться при своем мнении - держи его при себе.
|
| |
|
|
| _Dark_ | Дата: Среда, 03.08.2011, 10:02 | Сообщение # 10 |
|
Постоялец
Группа:
I'm V.I.P.
Сообщений: 379
Награды: 4
Город: Dark://core.dll
Репутация: 169
Замечания: 40%
Статус: 
| Ghost-X, спасибо, дополнил статью. Foх, SLICK, года три назад я и представить себе не мог, что через три года буду писать этот урок Спасибо.
Если баги возникают из ниоткуда - ты на правильном пути. (с)
|
| |
|
|
|
 |
|
 | |
| |
|