Важная информация
Страница 1 из 4 123 ... ПоследняяПоследняя
Показано с 1 по 10 из 33

Тема: Массивы и функции

  1. #1 Массивы и функции 
    Профи
    Регистрация
    09.11.2013
    Сообщений
    270
    Сказал(а) спасибо
    17
    Поблагодарили 80 раз(а) в 54 сообщениях
    Ребята, подскажите, как передавать массив в функцию в качестве аргумента и возвращать массив как результат функции
    Ответить с цитированием  
     

  2. #2  
    Супер модератор Аватар для >Quiet Snow<
    Регистрация
    11.04.2011
    Адрес
    Планета земля
    Сообщений
    3,935
    Сказал(а) спасибо
    1,845
    Поблагодарили 986 раз(а) в 844 сообщениях
    Записей в блоге
    1
    Это надо?

    FreeBasic Code:
    1. #include "crt/string.bi"
    2.  
    3. SUB Routine (InsideMas() AS INTEGER, ReturnMas() AS INTEGER)
    4.    InsideMas(1) = 33
    5.    MemCpy(@ReturnMas(LBOUND(ReturnMas)), @InsideMas(LBOUND(InsideMas)), _
    6.                     (UBOUND(ReturnMas) - LBOUND(ReturnMas) + 1) * SIZEOF(INTEGER))
    7. END SUB
    8.  
    9. DIM SourceMas(0 TO 1) AS INTEGER
    10. DIM NewMas(0 TO 1) AS INTEGER
    11.  
    12. SourceMas(0) = 5
    13. SourceMas(1) = 7
    14.  
    15. Routine(SourceMas(), NewMas())
    16.  
    17. PRINT NewMas(0), NewMas(1)
    18.  
    19. SLEEP

    Массивы должны быть одинаковые по размеру.

    Тут ещё читани, чувак fxm рекламирует свою функцию, которая якобы быстрее работает через строки:
    http://www.freebasic.net/forum/viewt...hp?f=2&t=19996

    Сам бы взял MemCpy и не стал бы париться, овчинка не стоит...
    Обучение прикладному программированию(по skype), качественно, недорого, 18+, вопросы в личку.
    «Если вы ничего не сделаете, я уверяю вас, ничего и не произойдёт» © Жак Фреско
    Ограниченно модерирую.
    Ответить с цитированием  
     

  3. Пользователь сказал cпасибо:

    ur_naz (05.05.2016)

  4. #3  
    Профи
    Регистрация
    09.11.2013
    Сообщений
    270
    Сказал(а) спасибо
    17
    Поблагодарили 80 раз(а) в 54 сообщениях
    Спасибо, но это не совсем то... Здесь процедура, она ничего не возвращает, а мне нужна функция, которая возвращает массив. И еще не понятно почему компилятор ругается на директивы ByRef/ByVal
    Ответить с цитированием  
     

  5. #4  
    Супер модератор Аватар для >Quiet Snow<
    Регистрация
    11.04.2011
    Адрес
    Планета земля
    Сообщений
    3,935
    Сказал(а) спасибо
    1,845
    Поблагодарили 986 раз(а) в 844 сообщениях
    Записей в блоге
    1
    а мне нужна функция, которая возвращает массив
    Такого не видел...может Стас подскажет. В любом случае возвращать в пустое место оно не может
    типа создавая новый(даже если бы синтаксически такая абилка была) только в точно такой же массив.
    А вышеуказанная процедура это и делает, пишет массив на массив, по сути возвращает.

    И еще не понятно почему компилятор ругается на директивы ByRef/ByVal
    Вроде бы допираю почему, т.к. разрабы зачем-то жёстко закрепили ByRef для массивов,
    или нужно что-то с директивами мутить.
    Обучение прикладному программированию(по skype), качественно, недорого, 18+, вопросы в личку.
    «Если вы ничего не сделаете, я уверяю вас, ничего и не произойдёт» © Жак Фреско
    Ограниченно модерирую.
    Ответить с цитированием  
     

  6. #5  
    Профи Аватар для stabud
    Регистрация
    05.01.2013
    Сообщений
    784
    Сказал(а) спасибо
    326
    Поблагодарили 348 раз(а) в 275 сообщениях
    Записей в блоге
    6
    Цитата Сообщение от ur_naz Посмотреть сообщение
    И еще не понятно почему компилятор ругается на директивы ByRef/ByVal
    Массив - это область памяти с определенным кол-вом данных. Передать его в функцию можно только через Byref (то есть по ссылке). Разработчики специально внесли предупреждение, чтобы кодер не занимался херней с массивами через Byval. Представь себе 2х-мерный массив на 100000 элементов. А теперь представь что эти все эти элементы надо передать через Byval (по значению). То есть каждую ячейку надо запихать в стек. А стек у программы как известно не резиновый! Поскольку массив передается по ссылке, то все манипуляции с ним в функции, отражаются на его реальных ячейках в основном коде.

    Сам массив вернуть нельзя, но можно вернуть указатель на его первый элемент. Получится что-то типа этого:

    FreeBasic Code:
    1. Function f() As Integer Ptr
    2. Static q(3) As Integer
    3. q(2)+=1
    4. Return @q(0)
    5. End Function
    6.  
    7. Dim i As Integer Ptr =  f()
    8.  
    9. ? i[2]
    10. f()
    11. ? i[2]
    12. f()
    13. ? i[2]
    14.  
    15. sleep



    Или , если все же нужен массив, например чтобы получать его границы, то возврат можно оформить через type, хотя выглядит это конечно превратно:

    FreeBasic Code:
    1. Type MM
    2. q(3) As Integer
    3. End Type
    4.  
    5. Function f() As MM Ptr
    6. Static tMM As MM
    7. tMM.q(2)+=1
    8. Return @tMM
    9. End Function
    10.  
    11. Dim i As MM Ptr =  f()
    12.  
    13. ? i->q(2)
    14. f()
    15. ? i->q(2)
    16. f()
    17. ? i->q(2)
    18.  
    19. Sleep


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

    Ну а как передавать массив в функцию уже показал в примере Алексей.
    Ответить с цитированием  
     

  7. Пользователь сказал cпасибо:

    >Quiet Snow< (06.05.2016)

  8. #6  
    Супер модератор Аватар для >Quiet Snow<
    Регистрация
    11.04.2011
    Адрес
    Планета земля
    Сообщений
    3,935
    Сказал(а) спасибо
    1,845
    Поблагодарили 986 раз(а) в 844 сообщениях
    Записей в блоге
    1
    В примерах , в функциях создаются статические массивы.
    Стас, скажи правильно думаю, что STATIC это в данном случае тоже самое что и

    Assembler Code:
    1. F    Proc
    2. Jmp  PrSt
    3. tMM  DD 3  DUP (0)
    4. PrSt:
    5.    . . .
    6. F    EndP


    Т.е. размещает внутри кода процедуры массив. Или всё таки бейсик его складывает в отдельный кусок данных,
    предназначенный для статических массивов? Вроде бы в винде нельзя просто так записывать данные в код,
    т.е. тип доступа после запуска для кода программы не может быть EXCUTE\READ\WRITE одновременно.


    UPD: Откомпилировал в ASM, всё таки в отдельную секцию складирует, тогда ладно...
    код
    Assembler Code:
    1. .intel_syntax noprefix
    2.  
    3. #BBB.BAS' compilation started at 10:50:41 (FreeBASIC 0.90.0)
    4.  
    5. .section .text
    6. .balign 16
    7.  
    8. .globl _F@0
    9. _F@0:
    10. push ebp
    11. mov ebp, esp
    12. sub esp, 4
    13. mov dword ptr [ebp-4], 0
    14. .Lt_0004:
    15. inc dword ptr [_Lt_0006+8]
    16. mov eax, offset _Lt_0006
    17. mov dword ptr [ebp-4], eax
    18. .Lt_0005:
    19. mov eax, dword ptr [ebp-4]
    20. mov esp, ebp
    21. pop ebp
    22. ret
    23.  
    24. .section .bss
    25. .balign 4
    26. .lcomm _Lt_0006,16
    27.  
    28. .section .text
    29. .balign 16
    30. _fb_ctor__BBB:
    31. push ebp
    32. mov ebp, esp
    33. sub esp, 4
    34. .Lt_0002:
    35. call _F@0
    36. mov dword ptr [ebp-4], eax
    37. push 1
    38. mov eax, dword ptr [ebp-4]
    39. push dword ptr [eax+8]
    40. push 0
    41. call _fb_PrintInt@12
    42. call _F@0
    43. push 1
    44. mov eax, dword ptr [ebp-4]
    45. push dword ptr [eax+8]
    46. push 0
    47. call _fb_PrintInt@12
    48. call _F@0
    49. push 1
    50. mov eax, dword ptr [ebp-4]
    51. push dword ptr [eax+8]
    52. push 0
    53. call _fb_PrintInt@12
    54. push -1
    55. call _fb_Sleep@4
    56. .Lt_0003:
    57. mov esp, ebp
    58. pop ebp
    59. ret
    60.  
    61. .section .fbctinf
    62. .ascii "-l\0"
    63. .ascii "user32\0"
    64.  
    65. #BBB.BAS' compilation took 0.0001649461708721489 secs
    66.  
    67. .section .ctors
    68. .int _fb_ctor__BBB
    Последний раз редактировалось >Quiet Snow<; 06.05.2016 в 11:59.
    Обучение прикладному программированию(по skype), качественно, недорого, 18+, вопросы в личку.
    «Если вы ничего не сделаете, я уверяю вас, ничего и не произойдёт» © Жак Фреско
    Ограниченно модерирую.
    Ответить с цитированием  
     

  9. #7  
    Профи Аватар для Сионист
    Регистрация
    21.01.2016
    Адрес
    Галактика Млечный Путь
    Сообщений
    509
    Сказал(а) спасибо
    11
    Поблагодарили 21 раз(а) в 20 сообщениях
    Некоторые языки позволяют присваивать целиком массив однотипному массиву и ограниченность стека этому не мешает, в этом случае логично разрешить функциям возвращать массивы.
    Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на си.
    Ответить с цитированием  
     

  10. #8  
    Супер модератор Аватар для >Quiet Snow<
    Регистрация
    11.04.2011
    Адрес
    Планета земля
    Сообщений
    3,935
    Сказал(а) спасибо
    1,845
    Поблагодарили 986 раз(а) в 844 сообщениях
    Записей в блоге
    1
    Цитата Сообщение от Сионист Посмотреть сообщение
    Некоторые языки
    Речь идёт о конкретном диалекте - FreeBasic и вопрос более чем конкретен. Прошу без оффтопа.
    Последний раз редактировалось >Quiet Snow<; 06.05.2016 в 14:59.
    Обучение прикладному программированию(по skype), качественно, недорого, 18+, вопросы в личку.
    «Если вы ничего не сделаете, я уверяю вас, ничего и не произойдёт» © Жак Фреско
    Ограниченно модерирую.
    Ответить с цитированием  
     

  11. #9  
    Разбирающийся
    Регистрация
    01.04.2015
    Сообщений
    59
    Сказал(а) спасибо
    3
    Поблагодарили 35 раз(а) в 27 сообщениях
    А теперь представь что эти все эти элементы надо передать через Byval (по значению). То есть каждую ячейку надо запихать в стек. А стек у программы как известно не резиновый!
    Зачем в стек помещать массив? Под массив можно выделить память и в стек поместить указатель на нее.
    Ответить с цитированием  
     

  12. #10  
    Профи Аватар для stabud
    Регистрация
    05.01.2013
    Сообщений
    784
    Сказал(а) спасибо
    326
    Поблагодарили 348 раз(а) в 275 сообщениях
    Записей в блоге
    6
    Цитата Сообщение от locm Посмотреть сообщение
    Зачем в стек помещать массив? Под массив можно выделить память и в стек поместить указатель на нее.
    locm , ты либо не прочитал как следует посты, либо не разобрался о чем идет речь.
    ur_naz спросил почему при использовании Byval\Byref компилятор ругается. Я ему и попытался объяснить, что массив в FB передается только через Byref или по ссылке (то бишь передается дескриптор на некоторый тип , в полях которого разная инфа, в том числе и указатель на первый элемент массива ). Так же пояснил, почему глупо передавать массив через Byval (по значению). Что бы тебе было понятно, при передаче параметра , используя Byval, создается копия передаваемого значения переменной и помещается в стек . Ну а раз массив без вариантов можно передать только по ссылке, то разработчики попросту запретили использовать спецификаторы (Byval\Byref) с массивами.
    Ответить с цитированием  
     

Страница 1 из 4 123 ... ПоследняяПоследняя
Информация о теме
Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. Табулирование функции на C++
    от jon547 в разделе C/C++
    Ответов: 2
    Последнее сообщение: 16.01.2016, 22:08
  2. Изменение цвета в функции SpeedButton1Click
    от Nikolay Gulikov в разделе С++ Builder
    Ответов: 0
    Последнее сообщение: 03.06.2014, 07:57
  3. Вычислить значение функции
    от оля в разделе Turbo Pascal
    Ответов: 9
    Последнее сообщение: 15.12.2011, 23:05
  4. Вычислить значение функции
    от Макс в разделе QBasic
    Ответов: 1
    Последнее сообщение: 06.12.2011, 04:08
  5. Функции и подпрограммы
    от nikita в разделе QBasic
    Ответов: 0
    Последнее сообщение: 04.05.2011, 17:37
Ваши права
  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •