возвращение данных из функций

Предыдущая тема Следующая тема Перейти вниз

возвращение данных из функций

Сообщение  Eric-S в Сб Авг 23, 2008 9:20 am

Глава посвящена тому, как можно вернуть значение из функции и для чего это нужно.


Одной из особеностей функции function являеться то, что она может возвращать значение. Процедуры sub этого не могут делать.

Получение значения из функции очень удобный и наглядный механизм. Правда он имеет свои ограничения.



что значит получение


Вы уже сталкивались с работой функции, при её вызове.

Вот например функция извлечения квадратного корня.

Код:

print sqr(25) ' выведет 5

Вызываем функцию {i]sqr()[/i], она извлекает квадратный корень. Результатом работы функции будет число 5, тоесть корень из 25. Это число подставляеться на место вызова функции. Очень похоже на то, как буд-то было действие в скобочках.

Код:

print 3 * (1 + 4)

Сначало считаеться выражение в скобочках 1 + 4, а потом, выражение переписываеться в виде:


Код:

print 3 * 5

И уже считаеться оно. Нам переписывать ничего не нужно. Компютер сам сосчитает действие в скобочках и подставит вместо них результат. Точно также происходит и с функцией. Наше выражение будет переписано и вместо sqr(25) на его месте будет уже результат (который вернула функция), цифра 5.


Код:

print 5

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


функция ввозвращает

Вызов функции это только вершина айзберга. Тело же самой функции, вот что интересно. О процедурах и функциях было написано раньше. Сейчас же мы разберём механизм возврата.


Код:

function myfunc() as integer
return 666 ' возвращаем число 666
end function

print myfunc() ' напечатает нам 666

Всё просто! Создаём функцию и return'ом возвращаем нужное значение.



тип данных

Во-первых При создании функции обязательно нужно указать тип данных, которые она будет возвращать.

Код:

function myfunc() as integer
end function

В этом примере, тип возвращаемых данных, указан как integer. Но он может быть любой, например string.

Код:

function myfunc() as string
end function


А во-вторых, возвращаемый тип данных, должен соответствовать указанному типу.

Код:

function myfunc() as string
return "Hello, world!"
end function


альтернативный синтаксис

Функция может возвращать значения несколькими разными способами.

Возвращает значение и заканчивает функцию.
Код:

return (out_value)

Устанавливает возвращаемое значение и продолжает функцию.
Код:

function = (out_value)

Можно также вместо слова function использовать имя функции.
Код:

function myfunc() as integer
myfunc = 222
end function
[/code]


ньюансы

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

Даже если вы ничего не возвращали, то функция всё равно возвращает стандартное значение соответствующего типа.

см. также:
процедуры, функции и свойства
передача аргументов в процедуры и функции

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: возвращение данных из функций

Сообщение  Gena в Ср Сен 09, 2009 10:26 pm

Можно вернуть только одно значение

Вроде как необязательно - ведь можно так:
Код:

#Include "fbgfx.bi"
Type MasInt
  adres as integer ptr
  dlina as integer
End Type
Declare Function rangd(razbr as integer, dln as integer) as MasInt
Dim As Integer x,y
Dim Massiv As MasInt
Massiv=rangd(255,101)
ScreenRes 640,480,32
For x=0 To 10
   For y=0 To 10
    PSet(x,y),RGB(Massiv.adres[x+y*10],0,0)
   Next
Next
Do
   Sleep 10
Loop Until MultiKey(fb.SC_ESCAPE)
Delete[] Massiv.adres

Function rangd(razbr as integer, dln as integer) as MasInt
Dim ret As MasInt,p As Integer
ret.dlina=dln
ret.adres=New Integer[ret.dlina]
For p=0 To dln-1
   ret.adres[p]=Rnd*razbr
Next
Return ret
End Function

Я надеюсь код понятен без коментов. (закомментирую завтра) )

Gena

Сообщения : 182
Дата регистрации : 2008-11-05
Возраст : 23
Откуда : Москва

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: возвращение данных из функций

Сообщение  Eric-S в Ср Сен 09, 2009 11:21 pm

Код понятен. Хотя для большей наглядности его можно было бы упростить.

А теперь я тебя разочарую.


Ты допустил сразу две ошибки в своих рассуждениях.

во-первых, когда ты объявляешь переменную определённой структуры,
и возвращаешь её - ты возвращаешь именно одно значение!
В твоём случае всего одна переменная ret.

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

Но повторяю, это не возвращение одного значения, а превращение нескольких значений в одно!



Вторая ошибка заключаеться в том, что по сути ты не возвращаешь значение. А только копию!
Это заблуждение крайне опастно!
Твоя программа в один, не очень чудестный день, выдасть тебе непонятную ошибку, а в структуре может оказаться что угодно.

Объекты из функций вообще нужно крайне аккуратно возвращать.
Это допустимо делать только в случаях когда поля содержат простые типы.
Или если поля сложных типов, но деструктор их не разрушает!

Объект можно возвращать, если у класса описан конструктор клонирования и оператор присвоения.

А вообще рекомендую использовать указатели на объекты. Создавать объекты оператором new() и разрушать delete.
таким образом ты не рескуешь потерять данные.

вот пример:
Код:


type coord
x as integer
y as integer
end type

function foot( x as integer, y as integer ) as coord ptr
dim c as coort ptr
c = new coord()

c->x = x
c->y = y
function = c
end function

dim a as coort ptr
a = foot( 12, 34 );

print a->x, a->y

delete a

Думаю, что мой пример так же не нуждаеться в комментариях?

Хотя в данном случае, класс достаточно прост, что его можно возвращать и так...
Но я однажды так же подумал, а потом в классе появилось ещё несколько полей и... Мне пришлось передлывать всю программу.

Кстати, возвращение указателя на объект, будет работать быстрее, ведь в этом случае объект не будет создаваться, поля копироваться из одного в другой, а старый разрушаться.
Ведь объект будет всё тем же!


Последний раз редактировалось: Eric-S (Вс Сен 13, 2009 3:31 am), всего редактировалось 2 раз(а)

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: возвращение данных из функций

Сообщение  Gena в Сб Сен 12, 2009 2:42 pm

Вроде не
c.x = x
c.y = y
а

c->x = x
c->y = y
Ещё можно вместо Function писать название функции, НО по какой-то причине нельзя делать так:
Код:
Function dgABCD(Tr as dgTriangleT) As dgPloskost
dgABCD.A = Tr.T(0).y*(Tr.T(1).z - Tr.T(2).z) + Tr.T(1).y*(Tr.T(2).z - Tr.T(0).z) + Tr.T(2).y*(Tr.T(0).z - Tr.T(1).z)
dgABCD.B = Tr.T(0).z*(Tr.T(1).x - Tr.T(2).x) + Tr.T(1).z*(Tr.T(2).x - Tr.T(0).x) + Tr.T(2).z*(Tr.T(0).x - Tr.T(1).x)
dgABCD.C = Tr.T(0).x*(Tr.T(1).y - Tr.T(2).y) + Tr.T(1).x*(Tr.T(2).y - Tr.T(0).y) + Tr.T(2).x*(Tr.T(0).y - Tr.T(1).y)
dgABCD.D =-( Tr.T(0).x*(Tr.T(1).y*Tr.T(2).z - Tr.T(2).y*Tr.T(1).z) + Tr.T(1).x*(Tr.T(2).y*Tr.T(0).z - Tr.T(0).y*Tr.T(2).z) + Tr.T(2).x*(Tr.T(0).y*Tr.T(1).z - Tr.T(1).y*Tr.T(0).z) )   
End Function

P.S. Какая разница между new() и new[]?

Gena

Сообщения : 182
Дата регистрации : 2008-11-05
Возраст : 23
Откуда : Москва

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: возвращение данных из функций

Сообщение  Eric-S в Сб Сен 12, 2009 4:43 pm

С оператором косвенного обращения, действительно ошибся. Прошу прощения.

new() выделяет память под объект и вызывает конструктор
new[] выделяет память под массив элементов.
Ха-эм. Я кажеться об этом уже писал:


Последний раз редактировалось: Eric-S (Вс Сен 13, 2009 10:06 am), всего редактировалось 1 раз(а)

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: возвращение данных из функций

Сообщение  Gena в Сб Сен 12, 2009 9:31 pm

Eric-S, поправь пост - народ не поймёт..
Да я помню, что уже писал, не нашёл. ))

Gena

Сообщения : 182
Дата регистрации : 2008-11-05
Возраст : 23
Откуда : Москва

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: возвращение данных из функций

Сообщение  Eric-S в Вс Сен 13, 2009 3:44 am

Gena пишет:Да я помню, что уже писал, не нашёл. ))

Операторы new и delete смотри конечно же здесь.

В низу и про new[].
А вообще я всё собираюсь про массивы писать. Статические и динамические.
Точнее даже начал, но вот смачного примера всё в голову не приходит.


Последний раз редактировалось: Eric-S (Вс Сен 13, 2009 10:10 am), всего редактировалось 1 раз(а)

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: возвращение данных из функций

Сообщение  Gena в Вс Сен 13, 2009 10:02 am

Я другое имел ввиду )))
Не

new() выделяет память под объект и вызывает конструктор
new() выделяет память под массив элементов.
а

new() выделяет память под объект и вызывает конструктор
new[] выделяет память под массив элементов.
))

Gena

Сообщения : 182
Дата регистрации : 2008-11-05
Возраст : 23
Откуда : Москва

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: возвращение данных из функций

Сообщение  Eric-S в Вс Сен 13, 2009 10:09 am

Ну что за жизнь!?
Хотел написать несколько нецензурных выражений, а нельзя!
Теперь исправил то?
Или мне ещё ошибки поискать?

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: возвращение данных из функций

Сообщение  Спонсируемый контент


Спонсируемый контент


Вернуться к началу Перейти вниз

Предыдущая тема Следующая тема Вернуться к началу


 
Права доступа к этому форуму:
Вы не можете отвечать на сообщения