[ Обновленные темы · Новые сообщения · Участники · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Форум » Моддинг » 5.1. Уроки Lua » Урок 4. Управляющие структуры. (Управление ходом программы. Циклы. Ветвления.)
Урок 4. Управляющие структуры.
Герыч
Админы
Сообщений: 1240
Реп: 60 / Инв: 5
Ну вот мы и узнали, как создавать переменные(написать имя переменной и присвоить ей значение), теперь надо добавить выполнению программы какую-то нелийность.
Что значит нелинейность? Это значит программа выполняется не построчно, а может повторять действия(циклы) и делать выбор между двумя ветвями выполнения(условное ветвление).
Итак, под ветвлением понимается такой момент в программе, когда в зависимости от текущих данных надо сделать одно из двух действий.
Все знают, что делить на ноль нельзя?
Правило можно записать так:
Code
Если знаменатель  =0 тогда
     нельзя делить!
иначе
     Можно делить числитель на знаменатель
конец

Теперь это можно спокойно перевести на lua:

Code
chislitel = 10
znamenatel=5
if znamenatel==0 then
     print("Division by zero!")
else
     print(chislitel/znamenatel)
end

Выполнив этот код, вы увидите на экране 2, что равно 10/5
Теперь поменяйте znamenatel=0. На экране будет грозная надпись Division by zero!, что значит деление на ноль.
Вроде пример очень простой, всем должно быть понятно. Данную конструкцию можно использовать по-разному. Во-первых, число действий для каждой ветки ветвления может быть >1. Использовать else необязательно.

Ещё в программе может быть цикл. Цикл - действие, повторяемое не 1 раз, а больше.
Для чего можно это использовать? Давайте сделаем глупую программку, которая выводит на экран 365 дней=)
Опять, сначала на русском, потом на lua-шном=):

Code

Для каждого дня от 1 до 365
     Написать на экране номер дня
Конец

Вот как это выглядит в lua:

Code

for i=1,365 do
     print("Day "..i)
end

Как видите, тут есть имя перенной i. У каждого такого цикла есть особая переменная-счётчик. Она изменяется от 1 до 365 каждый раз на 1.
При этом внутри цикла(эта внутренность называется телом цикла) переменную можно использовать как угодно.

Циклы можно вкладывать друг в друга. Выведем на экран таблицу умножения с помощью этого:

Code

stroka=""    --тут будем хранить текущую строку таблицы, а потом, когда она готова выводить на экран

--Делаем заголовок таблицы
stroka="   "
for j=1,9 do
     stroka=stroka.."  "..j  --Заголовок состоит из чисел от 1 до 9, разделённых 2-мя пробелами
end
print(stroka)   --Выводим на экран

for i=1,9 do     --выводим 9 строк
     stroka=i       --Пишем в первом столбике множитель
     for j=1,9 do   --для каждого столбика в строку выводим произведение
       proizvedenie=i*j
       if proizvedenie<10 then    --если элемент таблицы имеет 1 цифру, то надо добавить перед числом 2 пробела, иначе 1
         stroka=stroka.."  "..proizvedenie
       else
         stroka=stroka.." "..proizvedenie
       end
     end
     print(stroka)
end

У меня эта программа вывела следующий текст:

Code

      1  2  3  4  5  6  7  8  9
1  1  2  3  4  5  6  7  8  9
2  2  4  6  8 10 12 14 16 18
3  3  6  9 12 15 18 21 24 27
4  4  8 12 16 20 24 28 32 36
5  5 10 15 20 25 30 35 40 45
6  6 12 18 24 30 36 42 48 54
7  7 14 21 28 35 42 49 56 63
8  8 16 24 32 40 48 56 64 72
9  9 18 27 36 45 54 63 72 81

Что ещё можно сказать по циклам со счётчикам? Можно указывать шаг(то есть насколько меняется значение переменной):

Code

for i=1,100,2 do
     print(i)
end

Этот код выведет выведет все нечётные цифры от 1 до 99(то есть от 1 с шагом=2)
Шаг может быть отрицательным:
Code

for i=100,1,-1 do
     print(i)
end

Этот код выводит числа от 1 до 100 в порядке убывания, то есть:
Code
100
99
98
97
...

Чтобы досрочно прервать цикл есть оператор break:

Code

for i=1,100 do
     print(i)
     if i==50 then
       break
     end
end

Этот код выведет все числа от 1 до 50, но не до 100, потому что если i=50, то вызывается break.

Кроме цикла со счётчиком есть ещё и условные циклы двух типов
1) Цикл с предусловием
Этот цикл выполняется пока некоторое логическое выражение истинно(true) - условие продолжения.
Пример:

Code

x=0.1
while math.sin(x)>0 do
     print(x,math.sin(x))
     x=x+0.1
end

Тут выведется значения синуса, которые больше 0:

Code
0.1    0.099833416646828
0.2    0.19866933079506
0.3    0.29552020666134
0.4    0.38941834230865
0.5    0.4794255386042
0.6    0.564642  47339504
0.7    0.64 421768723769
0.8    0.71735609089952
0.9    0.78332690962748
1    0.8414709848079
1.1    0.89120736006144
1.2    0.93203908596723
1.3    0  .9635581854171 9
1.4    0.98544972998846
1.5    0.99749498660405
1.6    0.99957360304151
1.7    0.99166481045247
1.8    0.9738476308782
1.9    0.9463  0008768741
2    0.90 929742682568
2.1    0.86320936664887
2.2    0.80849640381959
2.3    0.74570521217672
2.4    0.67546318055115
2.5    0.59847214410396
2  .6    0.5155013718 2146
2.7    0.42737988023383
2.8    0.3349881501559
2.9    0.23924932921398
3    0.14112000805987
3.1    0.041580662433289

Как только x стало больше 3.14 синус x стал меньше 0 и цикл прервался.

Если в начале условие цикла не выполняется, то цикл ни разу не выполнится

2) Цикл с постусловием
Этот тип цикла даёт того, что тело цикла хотя бы 1 раз выполнится. При этом задаётся условие выхода из цикла(когда оно истинно, т.е. true, то цикл завершается)
Обычно его используют в такой ситуации, когда надо попробовать что-то сделать(хотя бы 1 раз), а если не вышло, то повторить ещё, и ещё, и ещё...)
Вот пример:

Code

n=6
math.randomseed(os.time())
math.random()
repeat
     i=math.random(n)
     print(i)
until i==n
print("After repeat .. until")
print(i)

Тут выводятся числа от 1 до 6, пока сичло не станет = 6. После цикла гарантированно i будет = 6

Code

math.randomseed(os.time())
math.random()

Этот код сбрасывает генератор случайных чисел(ибо при каждом запуске последовательность чисел будет повторяться и не будет случайной).

Code
i=math.random(n)

А этот записывает в i случайное число от 1 до 6

Ну всё, на это урок окончен. Самое важное я до вас донёс.



[Прошлый урок]|[Следующий урок]


________________________
__|____|____|____|____|__
|____|____|____|____|____|
__|___бицца головой___|__
|____|____|сюда|____|____|
__|____|____|____|____|__
|____|____|____|____|____|
 
SW_Krash
Проверенные
Сообщений: 818
Реп: 28 / Инв: 7
Quote (Герыч)
Code

math.randomseed(os.time())
math.random()

Этот код выводит сбрасывает генератор сулчайных чисел


мне непонятно только это... "выводит сбрасывает" - видать описка тут
А ещё понравилась прога вывода таблицы умножения... довольно интересное исполнение =)))


Всё что ни делается, делается в Китае(SW_Krash, 2009)
Мир делиться на два типа людей: Бездарные трудоголики и Талантливые лентяи. (firsacho 2008)
Я отрицаю вашу реальность и заменяю её своей!(Адам Севидж, 200x)
OFFTOP SWEAT OFFTOP(фольклор)

 
Герыч
Админы
Сообщений: 1240
Реп: 60 / Инв: 5
Quote (SW_Krash)
А ещё понравилась прога вывода таблицы умножения... довольно интересное исполнение =)))

Спасибо) старался)))
а ошибку поправил


________________________
__|____|____|____|____|__
|____|____|____|____|____|
__|___бицца головой___|__
|____|____|сюда|____|____|
__|____|____|____|____|__
|____|____|____|____|____|
 
SW_Krash
Проверенные
Сообщений: 818
Реп: 28 / Инв: 7
а ещё когда будем проходит 2-х мерные масивы сделаем таблицу умножения как масив... кстати а масив выводиться на экран норм как таблица???

Всё что ни делается, делается в Китае(SW_Krash, 2009)
Мир делиться на два типа людей: Бездарные трудоголики и Талантливые лентяи. (firsacho 2008)
Я отрицаю вашу реальность и заменяю её своей!(Адам Севидж, 200x)
OFFTOP SWEAT OFFTOP(фольклор)

 
Герыч
Админы
Сообщений: 1240
Реп: 60 / Инв: 5
Нет)
Code

a=1
b="asdf"
c=function (x) print(x) end
d={}
e=nil
f=true
print(a)
print(b)
print(c)
print(d)
print(e)
print(f)

выводит:
Code
1
asdf
function: 0044D8B0
table: 0044D610
nil
true

то есть для сложных типов выводит название типа и адрес в памяти


________________________
__|____|____|____|____|__
|____|____|____|____|____|
__|___бицца головой___|__
|____|____|сюда|____|____|
__|____|____|____|____|__
|____|____|____|____|____|
 
SW_Krash
Проверенные
Сообщений: 818
Реп: 28 / Инв: 7
хм... а можно отобразить таблицу как таблицу с помощью спец моделей???? а ещё можно ли вывести на экран функцию т.е. всё её тело???

Всё что ни делается, делается в Китае(SW_Krash, 2009)
Мир делиться на два типа людей: Бездарные трудоголики и Талантливые лентяи. (firsacho 2008)
Я отрицаю вашу реальность и заменяю её своей!(Адам Севидж, 200x)
OFFTOP SWEAT OFFTOP(фольклор)

 
Герыч
Админы
Сообщений: 1240
Реп: 60 / Инв: 5
таблицу да, функцию-нет, да в этом и нет смысла)

Как вывести таблицу? Вот такую вот штуковину я написал для этого:

Code
----------------------------------------------------
--Вывести на экран переданный параметр
--value     - выводимое значение
--recursive - выводить поддтаблицы в таблице?
--margin    - отступ(строка из пробелов)
function _echo(value,recursive,margin)
     margin=margin or " "
     local value_type=type(value)
     if value_type=="table" then
         io.write("table   = ")
         local key,field
         local is_empty=true
         for key in pairs(value) do
             is_empty=false
             break
         end
         if is_empty then
             io.write("<empty>")
         else
             local maxlen=0
             local key_type
             for key in pairs(value) do
                 key_type=type(key)
                 if key_type=="table" then
                     maxlen=math.max(maxlen,15)
                 elseif value_type=="string" then
                     maxlen=math.max(maxlen,string.len(key))
                 elseif value_type=="nil" then
                     maxlen=math.max(maxlen,3)
                 else
                     maxlen=math.max(maxlen,string.len(tostring(key)))
                 end
             end
             local keystring
             for key,field in pairs(value) do
                 io.write("\n"..margin)
                 if key_type=="table" then
                     io.write(key)
                     for i=16,maxlen do
                         io.write(" ")
                     end
                 elseif value_type=="string" then
                     io.write(key)
                     for i=string.len(key)+1,maxlen do
                         io.write(" ")
                     end
                 elseif value_type=="nil" then
                     io.write("nil")
                     for i=4,maxlen do
                         io.write(" ")
                     end
                 else
                     io.write(key)
                     for i=string.len(tostring(key))+1,maxlen do
                         io.write(" ")
                     end
                 end
                 io.write(" : ")
                 if type(field)=="table" then
                     if recursive then
                         _echo(field,true,margin.." ")
                     else
                         io.write("=")
                         io.write(field)
                     end
                 else
                     _echo(field,false,margin.." ")
                 end
             end
         end
     else
         if value_type=="string" then
             io.write("string   = ")
         elseif value_type=="number" then
             io.write("number   = ")
         elseif value_type=="boolean" then
             io.write("boolean  = ")
         elseif value_type=="nil" then
             io.write("nil      = ")
         elseif value_type=="thread" then
             io.write("thread   = ")
         elseif value_type=="userdata" then
             io.write("userdata = ")
         elseif value_type=="function" then
             io.write("function = ")
         end
         io.write(tostring(value))
     end
     if margin==" " then
         io.write("\n")
     end
end
-----------------------------------------------------
--Вывести на экран переданный параметр рекурсивно
--varname   - имя переменной(просто для красоты)
--value     - выводимое значение
function echo(value,varname)
     if varname then
         io.write(varname.." : ")
     end
     _echo(value,true)
end
-----------------------------------------------------

Конечно можно и покороче...
использовать так:

Code

echo("rrrr")
io.write("\n")

a=9392
echo(a,"a")
io.write("\n")

b={}
b.a=5533
b.b="afasfas"
b.c=function() print("hello") end
echo(b,"b")
io.write("\n")

b.d={}
b.d.a=523
b.d.g=55553
echo(b,"b")


________________________
__|____|____|____|____|__
|____|____|____|____|____|
__|___бицца головой___|__
|____|____|сюда|____|____|
__|____|____|____|____|__
|____|____|____|____|____|
 
๖ۣۜ₥4ǻ1™
Проверенные
Сообщений: 266
Реп: 5
у меня мозг запутался

Back the attack!!!




Нужен юзербар ? А нарисовать лень =) заходи

Go newgrounds!!

 
Герыч
Админы
Сообщений: 1240
Реп: 60 / Инв: 5
потому что надо по порядку с 1-го урока читать и пробовать всё на деле, придумывая себе примеры)

________________________
__|____|____|____|____|__
|____|____|____|____|____|
__|___бицца головой___|__
|____|____|сюда|____|____|
__|____|____|____|____|__
|____|____|____|____|____|
 
analiener
Проверенные
Сообщений: 382
Реп: 8
Герыч, я сделал прогу В первой строчке указывается число дня, месяца и года. Программа меняет число месяца на название или показывает, что число месяца введено неправильно=)
Code
date={20,4,1998}
month={"января", "февраля","марта","апреля","мая","июня","июля","августа","сентября","октября","ноября","декабря"}
forever=nil
fromever=nil
ever=99999
fo r forever=13,ever,1 do
month[forever]="\"ошибка\""
end
for fromever=0,-ever,-1 do
month[fromever]="\"ошибка\""
end
date[2]=month[date[2]]
birstday="Я родился "..date[1].."-ого "..date[2].." "..date[3].." г."
print(birstday)

Слава Герычу!








Умом Упячку не понять,
Аршином общим не измерить.
Упячку надо посещать!
В Упячку надо просто верить...
 
Новорожденные
Сообщений: 1
Реп: 0
Цитата analiener
forever=nil fromever=nil ever=99999 fo r forever=13,ever,1 do month[forever]="\"ошибка\"" end for fromever=0,-ever,-1 do month[fromever]="\"ошибка\"" end

Зачем искать возможно введенные не правильные числа, если лучше указать только правильные:
Например

Код
date=3
if(date>=1 and date<=12) then
print(date)
else
print('error: такого месяца еще не придумали')
end
 
Unaited
Админы
Сообщений: 1463
Реп: 92 / Инв: 13
Radish, ты разводишь некропостинг

 
killeroi
Хранители порядка
Сообщений: 1850
Реп: 88 / Инв: 9
Уроки никак к некропостингу не будут отнесены.

Как в старые добрые
 
Проверенные
Сообщений: 414
Реп: 5
Ну [WEC]SonicX прав

 
Заблокированные
Сообщений: 2357
Реп: 93 / Инв: 16
[WEC]SonicX,уроки - нет,а бредовые сообщения как у Radish - да.
 
Форум » Моддинг » 5.1. Уроки Lua » Урок 4. Управляющие структуры. (Управление ходом программы. Циклы. Ветвления.)
  • Страница 1 из 1
  • 1
Поиск: