Форум Pawn-Wiki.Ru - Воплоти мечту в реальность!: Return как Вернуть по-человечески - Форум Pawn-Wiki.Ru - Воплоти мечту в реальность!

Перейти к содержимому

  • (3 Страниц) +
  • 1
  • 2
  • 3
  • Вы не можете создать новую тему
  • Вы не можете ответить в тему

[ Урок ]
Return как Вернуть по-человечески Сугубо для тех, кто имел мало практики
Оценка: -----

#1
Пользователь офлайн   Nestyreff 

  • Stone tm
  • Вставить ник
  • Раскрыть информацию
Этот "Сборник" советов я решил написать, когда увидел прошлую статью на этом форуме по операторе Return.

Автор: Nestyreff

1. Что это такое? (Для новичков)

Оператор Return возвращает действие(число или другую функцию) при вызове функции, в которой он состоит. Данный оператор используется почти во всех языках программирования и является одним из ключевых теорий ЯП(остальные: переменные, функции, операторы и систематика). Стоит также отметить, что если Вы не указываете, что нужно вернуть, то по умолчанию функция будет возвращать нуль. Оператор Return в Pawn оперирует виртуальной машиной(компилятором amx). Оператор Return может возвращать переменную по ссылке (new) и многое другое.(Спасибо SooBad)

2. Вернуть то, что не нужно, но получить пользу.

Иногда нам нужно закончить функцию, чтобы не наделать чего еще плохого. Зачастую функции заканчиваются через return. Пример:
OnGamemodeInit
{
  return 1;
}



Функция в любом случае будет возвращать 1.
Теперь другой:
OnGamemodeInit()
{
  if(a == b) return StopServer();
  return 1;
}



Теперь, если условие окажется правдивым, то сервер не запуститься, однако, если бы я использовал вместо return, допустим скобки, например:
OnGamemodeInit()
{
  if(a == b)
   {
     MTA("Wiu Wiu");
   }
  return StopServer();
}



Теперь всё изменилось, теперь как раз, если условие не окажется правдивым или всё-таки окажется, то return StopServer(); всё равно будет работать и останавливать сервер,чтобы этого не было нужно в условие добавить "return 1;"
Любая функция должна что-то возвращать и любая функция оканчивается на return. Другими словами, return оканчивает действие функции и может быть вызван в необходимое для Вас время.

3. Return в командах.

Return в OnPlayerCommandText может возвращать true или false. Зачем?
if(strcmp("/s") == true) // Ух не помню, как его там использовать :)
{
   return true;
}



Теперь return true не просто заканчивает использование функции strcmp в условии, но и означает, что команда /s выполнена правильно. Если же, мы напишем return false; , то это будет означать обратное: функция завершена, команда выполнена неверно и нашему игроку, использовавшему команду, высветиться сообщение о неизвестной команде.

4. Return в рекурсии.

Одним из способов к рекурсии это бесконечный return. Как ни крути, но рекурсия это самое ненужное в коде, мало того, что сервер будет жутко лагать, так еще и другие функции будут выполняться не правильно.
Пример рекурсии:
stock S()
{
  return S;
}



Таким образом из функции S будет вызываться сама эта функция S и это действие будет происходить бесконечно. Другой пример рекурсии:
public OnPlayerConnect(playerid)
{
  OnPlayerConnect(playerid);
  return 1;
}



В итоге ничего не изменилось... добавили мы return 1 или не добавили, всё равно рекурсия есть(в этом её подвох). Следите за тем, чтобы функция не вызывалась сама из себя.

5. Использование Return в выражениях.

Пример наглядного использования:
new a;
new b;
if(a == b) return a;
if(a == b) return b;



Как думаете, что вернёт функция с таким кодом? - Думаете и a и b? А вот и нет... функция с таким кодом вернёт только a, так как возвращение a находится в первом условии, после того, как а будет возвращено, функция и другие условия выполняться не будут.
Другой пример:
new a;
new b;
if(a != 1) a = 1;
if(a == 1) a = 0;



Смотрите, без return мы никогда не выполним первое условие. Тоесть условие будет сначала делать a единицей, а потом снова нулём. Чтобы такого не было нужно использовать:
new a;
new b;
if(a != 1)
{ 
 a = 1;
 return 1;
}
if(a == 1)
{
  a = 0;
  return 1;
}



Теперь то условия будут выполняться правильно.
Также return может возвращать число, как выражение:
stock ReturnOne()
{
  return 2\2;
}


Таким образом в Return будет подсчитываться число, которое нужно вернуть и вернёт единицу.

6. Return вызывает подмогу. (by Skeif)

Иногда Return может возвращать значение из другой функции. Пример:
stock ReturnKick(playerid)
{
  SaveAccount(playerid);
  return Kick(playerid);
}



Теперь мы не просто вернули функцию кика игрока, но и перед этим сохранили его аккаунт. Стоит заметить, что Kick(); вернёт еще и своё значение (return 1) и поэтому функция ReturnKick(playerid) будет возвращать 1, а 1 = 1.
Как это использовать? Вот так:
stock ReturnKick(playerid)
{
  SaveAccount(playerid);
  if(Admin[playerid]) return 0;
  return Kick(playerid);
}
public OnPlayerCheat(playerid, idcheat)
{
 if(ReturnKick(playerid) == 0) return SendClientMessage(playerid, -1, "Так как Вы администратор, Вы не были кикнуты за читы"); // Так как ReturnKick при удачном кике возвращает единицу
 return ReturnKick(playerid); // Если условие не дало "Добро", то кикаем игрока.
}



Прошу обратить внимание на то, что ReturnKick не возвращает единицу, а возвращает другую функцию, которая в свою очередь уже возвращает 1.
Есть еще одно "Но": В ReturnKick мы сделали проверку на админа, и если игрок админ, то функция вернёт 0. Это мы используем в сравнении в if в OnPlayerCheat. Такие махинации очень полезны в использовании.

7. Подобия на Return. (Спасибо Hidden)
new i = 8;
loop_start:
if (i < 10)
{
printf("Число: %i", i);
i++;
goto loop_start;
}

В этом цикле мы создаём переменную со значением 8 (new i = 8), присваиваем циклу loop_start проверку на значение i (if(i < 10)). Если значение истинно, то есть i действительно меньше 10, то выводим значение переменной i, прибавляем к этой переменной единицу и с помощью функции goto запускаем цикл снова (goto loop_start;), только теперь i будет равняться 9. И так далее. В итоге, можно понять, что goto позволяет "механически" выйти из цикла. Правда, return тоже может выполнять роль goto, но не всегда.

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

Пример:
for(new i; i < MAX_PLAYERS; i++)
{
  if(i == 10) continue;
}



Конечно, такой цикл абсолютно бесполезен, но суть понятна. Теперь если шаг i будет равен 10, то никаких последующих действий исполнено не будет, а будет идти следующий шаг 11.

Break используется для полного остановления цикла без последующих шагов. Думаю тут понятно, так как он аналогичен Continue.

8. Return возвращает несколько значений.

По мимо того, что return может вернуть одно значение или вызвать другую функцию, он может вернуть несколько значений.

Но как же вернуть сразу несколько значений? - Очень просто:

public OnPlayerConnect(playerid)
{
 new mas[2] = {0, 2}; // массив имеет два значения в 1 ячейке 0, а во второй 2.
 return mas;
}



Таким образом мы возвращаем массив данных, тоесть несколько значений.
Если говорить о байтах памяти, то мы можем вернуть даже строку или Char переменную:

stock convert(symbal)
{
 new Char:Us[] = InUTF8(symbal);
 return Us;
}


Таким образом, мы вернули первый символ шифровки заданного символа в UTF8 (инклуд с InUTF8 скоро тоже опишу). Return также может возвращать и логические переменные, однако стоит помнить, что true и false это не ряд данных, а лишь одно значение: 0 - false и 1 - true, поэтому назвать такие операции многовозвращающими нельзя.

Мы можем вернуть определённую ячейку из массива:
stock getLevel(playerid)
{
 return PlayerInfo[playerid][Level];
}



Чтобы Вам было понятнее, то почитайте еще вот этот урок: http://pawn-wiki.ru/...__1#entry184133

Урок-сборник будет дополняться мной.

Сообщение отредактировал Nestyreff: 21 Апрель 2018 - 23:42

4

#2
Пользователь офлайн   Skeif 

  • Эксперт
  • Вставить ник
  • Раскрыть информацию

Цитата

Теперь всё изменилось, теперь как раз, если условие не окажется правдивым или всё-таки окажется, то return StopServer(); всё равно будет работать и останавливать сервер


Сервер остановит и вернет какое-то значение из функции StopServer()

И ты еще забыл добавить раздел с возвращением функции, которая вернет какое-то значение
К примеру:
stock Test()
{
	return Test2();
}
stock Test2()
{
	return 1;
}

В данном примере, функция Test() вернет значение из функции Test2, которая возвращает 1.

Сообщение отредактировал Skeif: 14 Апрель 2018 - 08:07

0

#3
Пользователь офлайн   SooBad 

  • [Свободно]
  • Вставить ник
  • Раскрыть информацию
Стоит добавить инфу о том, зачем именно существует данный оператор (углубиться, так сказать), а также отметить факт того, что любая функция по-дефолту возвращает нуль.
0

#4
Пользователь офлайн   Nestyreff 

  • Stone tm
  • Вставить ник
  • Раскрыть информацию

Просмотр сообщенияSooBad (14 Апрель 2018 - 09:05) писал:

Стоит добавить инфу о том, зачем именно существует данный оператор (углубиться, так сказать), а также отметить факт того, что любая функция по-дефолту возвращает нуль.

Я пока создал пустую тему. В дальнейшем я бы хотел её расширять. И всю информацию про Return и советы по его использованию. Щас добавим)
0

#5
Пользователь офлайн   Nestyreff 

  • Stone tm
  • Вставить ник
  • Раскрыть информацию
Обновил и добавил пункт 6.
0

#6
Пользователь офлайн   SooBad 

  • [Свободно]
  • Вставить ник
  • Раскрыть информацию
Т.к. тема будет расширяться, думаю, на своё усмотрение сможешь взять что-то из нижеописанного (постараюсь донести понятным языком):

Оператор возврата return имеет два важных применения: во-первых, он обеспечивает немедленный выход из функции, т.е. заставляет выполняющуюся программу передать управление коду, вызвавшему функцию, во-вторых, этот оператор можно использовать для того, чтобы возвратить значение. В случае с pawn, оператор возврата манипулирует виртуальной машиной.

Стоит добавить, что оператор имеет возможность возвращать строки (массивы) и то, что построение хуков (перехватов) также невозможно без участия return.
Оператор возврата можно использовать как альтернативу оператору безусловного перехода goto, для выхода из цикла (но далеко не всегда).
Также return полностью поддерживает работу с переменными, которые передаются по ссылке.

Сообщение отредактировал SooBad: 14 Апрель 2018 - 12:33

1

#7
Пользователь офлайн   Nestyreff 

  • Stone tm
  • Вставить ник
  • Раскрыть информацию

Просмотр сообщенияSooBad (14 Апрель 2018 - 12:31) писал:

Нажмите сюда, чтобы прочитать это сообщение. [Показать]

Хмм...Ну у тебя больше определение.Я думаю вынесу немного информации, но подам ее как для новичков)
0

#8
Пользователь офлайн   SooBad 

  • [Свободно]
  • Вставить ник
  • Раскрыть информацию

Просмотр сообщенияNestyreff (14 Апрель 2018 - 15:30) писал:

Хмм...Ну у тебя больше определение.Я думаю вынесу немного информации, но подам ее как для новичков)

Её и подать нужно правильно, дабы не вызвать сомнений в правдивости информации.
Шило на мыло тоже не стоит заменять, с целью "объяснить понятней") (Дело, конечно, твоё, и я ни в коем случае не заявляю, что написанный мною выше пост абсолютли райт).
0

#9
Пользователь офлайн   Nestyreff 

  • Stone tm
  • Вставить ник
  • Раскрыть информацию

Просмотр сообщенияSooBad (14 Апрель 2018 - 16:36) писал:

Нажмите сюда, чтобы прочитать это сообщение. [Показать]

Это то понятно)
0

#10
Пользователь офлайн   GAWESOME 

  • Павно-программист
  • Вставить ник
  • Раскрыть информацию
сделайте еще гайд про оператор + а то мене не понятно как он работает
0

Поделиться темой:


  • (3 Страниц) +
  • 1
  • 2
  • 3
  • Вы не можете создать новую тему
  • Вы не можете ответить в тему

1 человек читают эту тему
0 пользователей, 1 гостей, 0 скрытых пользователей