Помогни ни да направим Uroci.net по - богат! Добави урок

Урок 2: Видове променливи, Масиви, Стрингове, Функции в Pawn

taffch0   трудност:    видян: 6301

Съдържание:

    1. Променливите
    2. Видовете променливи
      2.1. Integer
      2.2. Float
      2.3. Booleans (булевите променливи, указващи дали дадено твърдение е вярно (TRUE - 1) или лъжа (FALSE - 0))

    4. Масивите
    5. Стринговете
    6. Функции



Променливи

За да съхраним временно някаква по вид информация, ние използваме променливите.
Променливите могат да съдържат числа, символи и стрингове.

За да декларираме променлива е нужно да напишем
Код:
1
new IME_NA_PROMENLIVATA


Важно е да се отбележе, че Small има 3 вида типове за деклариране на променливите.
По подразбиране е обикновено цяло число или още казано интежер.
Името на променливата трябва да започва с буква. Може да съдържа всички букви в двата регистъра (горен и долен): A-Z , a-z , цифри в обхвата 0-9 и долна черта "_".
Много важно е да знаете че имената на променливите са чувствителни към регистъра.
Тоест, ако имате декларирана променлива "Test" и отделно още една на име "test" - те са независими една от друга и съответно могат да приемат едновременно различни стойности без да си пречат по някакъв начин.

Както казах по-горе, променливите се делят на няколко вида според съдържанието си.

ИНТЕЖЕР

За да дефинираме някаква променлива, със съдържание интежер число (целите числа) трябва да напишете:
Код:
1
new a=6


Ето и няколко други примера:
Код:
1
2
3
4
new a            // Декларираме празна променлива
new b=5          // Декларираме променливата b и й зачисляваме стойност 5
new c=5.0        // Тук обаче имаме грешка ! Не можем да слагаме за стойност числа с плаваща точка (За целта идва Float променвлите)
new d="test"    // "test" не е никакво число, следователно тази променлива се явява невалидна 


За да спестявате редове, можете да декларирате и променливите си на един ред, изброявайки ги просто с по една запетайка ",".
Също така за по пригледност, можете на по-големите числа да им отделяте десетиците, стотиците, хилядните и т.н. с долна черта "_". Но и никакъв не е проблема да си ги напишете нацяло - Pawn няма да се обърка.
Примерно искате да декларирате променлива chislo със стойност 100000, и трябва да напишете:
Код:
1
new chislo 100000

Но можете да го запишете и по този начин:
Код:
1
new chislo 100_000

.. същото е.

Ето и един простичък пример, как да декларирате няколко променливи на един и същ ред:
Код:
1
2
new e,f,g,h
new x=7y=3


ПЛАВАЩИ (Float)
Също така както казах, можете да декларирате променливите си и като "Float", което ще значи че могат да съдържат в себе си числа с десетична запетая.
Или с други думи - числа с плаваща точка/запетая.
Код:
1
2
3
4
new Float:a            // Декларираме float променлива без никаква стойност
new Float:b=5.3        // Декларираме променливата "b" и й присвояваме стойност = 5.3
new Float:c=5          // Това е също правилно, но компилатора ще ви даде warning при компилиране
new Float:d="test"    // Това е неправилно, тъй като "test" не е никакво число, камоли пък float 


Също така можете да направите и следното:
Код:
1
2
3
4
5
6
//float(ЧИСЛО-n) е функция, която взема число "n" и го прави плаващо (за да не ви дава warning компилатора при компилиране)
new Float:promenliva float(5)
new 
Float:promenliva2 5.0     
new Float:promenliva3 1.0*5
new promenliva4 floatround(5.0)     
//Бележка: floatround(n) е функция, която взема числото "n" и го закръгля 

Отбележете също така че разстоянието между = не е от значение.

БУЛЕВИ
Това е последния тип променлива.
Много е простичка, тя винаги е или "истинна" или "лъжлива (булева)" или тъй наречените TRUE / FALSE.
Код:
1
2
new bool:Ubit_li_e_zalojnika        // Декларира променлива Ubit_li_e_zalojnika автоматично със стойност FALSE (лъжа)
new bool:Ubit_li_e_zalojnika=true      // Декларира Ubit_li_e_zalojnika със стойност TRUE 


Няма да се спирам много на този вид променлива, защото няма да ви трябва за сега и в процеса на работа ще я видите и в действие.
Но на кратко, може да се ползва за return-ване (връщане) на някакъв по вид резултат от някаква проверка (примерно).
Не искам да давам пример с проверки, защото още не сме стигнали до тях и не искам да ви обърквам.
За сега така ще оставим нещата, а пък ако сте заинтерисовани много, пишете и ще ви дам няколко примерчета.


Масиви

Масивите служат както променливите за да съхраняват някаква определена информация.
Предимство на масивите е че можете да записвате много стойности и то само в една променлива.
Масивите следват същите правила като обикновените променливи и се делят на същите типа.
Можете да дефинирате също така в големи скоби колко стойности да може да събере даден масив.
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// Декларираме променлива "Players", която ще побира в себе си 32 (в случая) числа.
new Players[32]
 
// Сега спокойно можем да запишем каквото си искаме в тези 32 слота, които сме направили в масива.
// Слотовете са номерирани и започват от 0 до n - 1. В тоя случай от 0 до 31 (което си е 32)
// Бележка: Всеки слот започва от 0
 
// Присвояваме стойност петица за слот 0 в масива
Players[0] = 5
 
// Така слагаме за слот 1, това, което сме записали за слот 0 (в случая е петица)
Players[1] = Players[0]
 
// Това тук е грешно ! 
// Въпреки че са 32 слота, те са номерирани както казах от 0 до 31.
// Ако направите същата грешка, компилатора ще върне грешка че сте излязли от обхвата на масива (index out of bounds)
Players[32] = 15
 
// Това тук също е грешно
Players[-1] = 6
 
new 3
// Както и това  
// "a" трябва да е константо число
new GreshenMasiv[a]
 
// Горният начин, би трябва да изглежда така:
const 3
new PravilenMasiv[c]
 
// Също така можете да използвате и директиви (за повече информация, прочетете по-долу)
 
#define RAZMER_NA_MASIVA 3
new masiv[RAZMER_NA_MASIVA


Масивите също така могат да бъдат декларирани като група от данни:
Код:
1
2
new chisla[4] = {0,1,2,3}
// Забележете броя на цифрите и размера на масива ! 


Също така можете да използвате всеки един тип данни с масиви:
Код:
1
2
3
4
// Масив с плаващи числа
new Float:Numbers[4] = {0.01.22.43.8}
// Масив с булеви данни.
new bool:playerHasGun[33] = {true, ...} 



Стрингове

При стринговете отпада декларирането на типа на променливата.
Стринговете технически са числа.
Стринга е вид масив от числа, които се превеждат/трансформират към ASCII символи.
Веднага давам и пример:

Код:
1
2
3
4
// Така ще декларираме масив moqString, който да съдържа информацията "test"
// Ще съдържа 5 слота, защото са 4ри символа 
// Последният слот е запазен за числото 0, което всъщност казва на engine-а на pawn че това е стринг. И затова винаги трябва да имаме едно на ум!
new moqString[] = "test" 


Следният пример показва абсолютно същото нещо със същото значение, но е по-дълго и не се препоръчва.
Този начин сработва, тъй като всеки един символ от стринга "test" се е запазил в определен слот в масив.

Код:
1
2
3
4
5
6
new moqString[5]
moqString[0] = 't'
moqString[1] = 'e'
moqString[2] = 's'
moqString[3] = 't'
moqString[4] = 0


Напълно грешно е обаче това:
Код:
1
2
3
new moqString[6]
moqString "Hello"     // Не валидно !
moqString[0] = "Hello"  // Не валидно ! 


За да запишете някаква информация в стринг, използвайте copy() функцията или format() , formatex:
Код:
1
2
3
4
5
6
7
8
new String[7]
copy(String6"Hello")

new 
string2[7]
format(string26"Hello")

new 
string3[7]
formatex(string36"Hello"


Разликите между функциите ще откриете в документацията: http://amxmodxbg.org/doc

.. сега обърнете внимание на това, че копирахме 6 клетки от масива в масив държащ 7.
Ако трябваше да копираме 7 байта в този масив, copy() функцията щеше да копира допълнителен байт за празният (null) символ и да развали масива.

Ето и още няколко примера:
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// copy() е функция, която приема 3 параметъра
copy(дестинация[], дължинаизточник[])
// Копира даден стринг, намиращ се в "източник[]" масива и го поставя в "дестинация[]" масива, но копира само до "дължина".
 
// И на последно място, за да ви докажа че стринга наистина е масив от числа, това е напълно валидно:
new test[7]
test[0] = 65
test
[1] = 77
test
[2] = 88
test
[3] = 88
test
[4] = 66
test
[5] = 71
test
[6] = 0
// Така ще присвоим стойност за променливата "test", стойността "AMXXBG". Невероятно, но факт. 



Функции


Pawn ви позволява да си дефинирате и декларирате свои собствени функции, без които нямаше да е толкова разнообразно всичко.
Функциите биха могли да ви помогнат с това че можете да ги използвате колкото си искате пъти на различни места и ще ви спести излишен код.
Особеното на функциите е че, те по принцип трябва да връщат накяква стойност.
За да върне някаква стойност, се използва return командата, която веднага след използването й, прекъсва изпълнението на функцията и връща съответната стойност.
Ето и един простичък пример:
Код:
1
2
3
4
5
6
amxmodxbg() {
       
log_amx("Tova e vtora chast ot uroka za AMX Mod X scriptiraneto !")
 
       return 
1
}
amxmodxbg() 


Нека и да разтълкуваме всичко по горепосоченият код.
    amxmodxbg - е името на самата функция
    () - в скобичките се слагат параметрите, които функцията да присвоява и след това да си ги използва в тялото (по-надолу ще видите и такива примери)
    { ..... } - Тялото на функцията се огражда от тези скобички. Обърнете внимание на първата че е: { , а крайната - затваряща е }
    log_amx("Tova e vtora chast ot uroka za AMX Mod X scriptiraneto !") - log_amx е функция, която логва даден текст в сървърната конзола
    return 1 - връщаме единица


Тук можете да видите и пример как функцията може да приема някакви параметри:
Код:
1
2
3
4
5
6
7
8
9
umnojenie(ab) {
   new 
rezultat b
 
   
return rezultat
}
 
new 
chislo1 5
new chislo2 9
new rezultat umnojenie(chislo1chislo2


Както вече би трябвало да сте разбрали, името на функцията ни е "umnojenie" (и би трябвало да се досетите какво ще прави)
В скобичките, след името й са двата параметъра (a и b), която тя присвоява.
След това декларираме нова променлива rezultat, която ще извърши умножението на параметъра "a" и "b" и съответно ще го запази в себе си.
След това връщаме с return резултата, който сме получили.

.. до тук с функцията. Нека да разгледаме и как да я извикаме:

Декларираме променливите chislo1 и chislo2, като им присвояваме някакви стойности (които, след това ще умножим) и накрая създаваме още една променлива, която ще съдържа резултата, върнат от функцията ни umnojenie.

Ето и друг пример:
Код:
1
2
3
4
5
6
7
umnojenie(ab) {
   new 
rezultat b
 
   
return rezultat
}

new 
rezultat umnojenie(65

.. където rezultat ще приеме стойност 40, a в горният пример 45 Smile


Когато давате параметри към дадена функция, се нарича "преминаване" (passing). Можете да прекарате каквито и да е било по тип данни.
.. било то масиви, float и т.н.

Ето една примерна функция, която ще събере 2 float числа:
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
Float:add_two_floats(Float:firstFloat:second)
{
   new 
Float:sum first second
 
   
return sum
}
 
new 
Float:a
new Float:b
5.0
6.3
new Float:c
add_two_floats(a+b


И нека да я разтълкуваме:
    1. Декларираме функция, която приема две float стойности.
    2. Декларираме вътре във функцията променлива sum от типа float, която ще сумира двата параметъра
    3. Връщаме като резултат от функцията стойността на променливата sum, в която вече е отговора


Както бях писал, можете да използвате и масиви като параметри.
Но тук не е нужно да определяте размера на масива, но все пак ако го определите, трябва да ста сигурни че извиквате функцията с масив, който е напълно еднакъв по размер и тип.

Пример:
Код:
1
2
3
4
5
6
7
8
add_two_from_array(array[], ab)
{
   new 
first = array[a]
   new 
second = array[б]
   new 
sum umnojenie(firstsecond)   // Използваме нашата функция "umnojenie", която декларирахме по-горе в урока
 
   
return sum


Отбележете че, когато прекарвате масиви през функция, те преминават, както се казва "by referance".
.. хехе, не разбрахте нали ? Smile
Сега ще се опитам да ви ги обесня малко нещата като вмъкна една отбивка към всичко казано до сега:

Има два начина за преминаване на аргументи/параметри към функция.
Първия начин се нарича "call by value" или на български "извикване по стойност, но иначе е се вика по копиране" и другия метод е "call by referance", или на български: "извикване чрез преписване".

Първият, който казах е "call by value" (чрез копиране): Знаете че при слагането на параметър във функция, той отива вътре във функцията и от там насетне се използва в нея.
Но всъщност това не е точно така. Тъй като по този метод променливата не отива във функцията, а се копира и използва само нейната стойност.
И тъй като се копира само стойността, а не променливата заедно с нея, всяка промяна на "преминатата" променлива през функцията не се запазва извън нея, тоест резултата няма да има ефект над по-нататъшните действия извън тази функция за променливата, която сме използвали.

Сега ще ви го изесня с един прост пример:
Да предположим че имаме променлива със стойност = 6 преди да я извикаме във функцията.
Код:
1
2
3
4
5
6
7
8
9
subirane(a) {
   new 
rezultat a
   a 
3
 
   
return rezultat
}
 
new 
6
new rezultat subirane(a


Резултата ще бъде равен на 10

Тъй като този метод копира и използва единствено стойността на променливата (в случая a) без самата нея, стойността на променливата ще продължава да бъде = 6, тоест няма да е = 10.
И ако желаете, пак можете да направите няколко пресмятания, но предходните резултати, няма да влияят върху стойностите, които ще влязат във функцията при извикването й.
Те отново ще са си = 6 и съответно, резултата винаги ще е 10, освен ако не използваме променливата "a" и в други функции.
кода по-горе написа:
Код:
1
new 6


"Call by Reference" (извикване чрез преписване)
В този случай самата променлива се използва за параметър/аргумент.
Иначе с прости думи казано, самият адрес до променливата преминава за параметър и върнатата стойността от функцията се използва за постоянна стойност, а не като при другият метод - само за временно ползване.

Ето още едно примерче:
Да предположим че сме декларирали променлива със стойност 2 (преди извикването на функцията)
Код:
1
2
3
4
5
6
7
8
9
subirane(&a) {
   new 
rezultat a
   a 
1
 
   
return rezultat
}
 
new 
2
new rezultat subirane(a

.. сега стойността която a ще приеме дори след извикването на функцията ще е 3.
Ето видяхте ли сега разликите ? .. резултата се запаметява в променливата (или по-точно се преписва, но както искате си го запомнете)

Надявам се че съм обяснил добре и сте разбрали чрез примерчетата и обесненията, които дадох какво значат тези два метода.

Та да се върнем на нашата тема с масивите !
При преминаването на масиви през функция, те минават през 2рият метод, за който споменах (чрез преписване / by reference).
Тъй като нормалните променливи преминат през функцията, те се копират в паметта и копираната част се изпраща до функцията и след това се трие (и за това не се "запаметява" след използването й)
Но тук с масивите не стоят нещата по този начин. Тъй като масивите могат да бъдат много големи и затова се преписват, вместо да се копират.
Това ще рече че ако промените масива във функцията, той ще бъде променен и за след това.

И тук ще дам един пример:
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Тази функция ще размени слотовете a и b вътре в който и да е било масив, преминат към функцията
swap_slots(masiv[], ac)
{
   
// Обърнете внимание, че е нужно да задържим един от слотовете, преди да ги разменим.
   // В противен случай няма как да стане да им разменим стойностите.
   // Ако имаме a и c, правим c да е еквивалентна на a, като елиминираме по този начин оригиналната/първоначалната стойност за c

   
new temp

   temp 
masiv[c]
   
masiv[c] = masiv[a]
   
masiv[a] = temp
}
 
new 
myArray[2]
myArray[0] = 5
myArray
[1] = 6
swap_slots
(myArray01)
//myArray[0] ще е 6, а пък myArray[1] ще бъде 5 


Но можете да предотвратите промяната на масивите, като при декларирането им ги укажите като "константни".

Код:
1
2
3
4
5
6
7
8
add_two_from_array(const masiv[], ac)
{
   new 
first masiv[a]
   new 
second masiv[c]
   new 
sum add_two_from_array(firstsecond)
   return 
sum
}
// Сега когато използваме функцията ще бъдем сигурни че масива, няма да бъде променен по никакъв начин. 


Тази функция променя преминаващия масив, който предварително е деклариран че е константен
Код:
1
2
3
4
nepravilna_funkciq(const array[])
{
   array[
0] = 0

.. но тъй като знаем че след като сложим const пред името на масива, той не може да бъде променян... Следователно номера няма да мине..

Реших с урока да спра до тук и да направя 3та част, тъй като този стана големичък.
Очаквайте и продължението на този урок !




Преписването е забранено.



Регистрирайте се, за да добавите коментар


Калдейта ЕООД - © 2003-2010. Всички права запазени.
Препоръчваме: Национален Бизнес | Bomba.bg | IT Новини | Диплома.бг | TRAVEL туризъм | Реферати | AmAm.bg | Иде.ли | Курсови работи | Фото Форум | Spodeli.net | Фото-Култ | Atol.bg | Elmaz.com | MobileBulgaria.com | Казанлък.Com