Форум программистов, компьютерный форум, киберфорум
Наши страницы
Basic
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.63/8: Рейтинг темы: голосов - 8, средняя оценка - 4.63
Quiet Snow
4416 / 1313 / 378
Регистрация: 25.04.2010
Сообщений: 3,409
1

Синтаксические особенности FreeBasic

08.11.2012, 13:28. Просмотров 1678. Ответов 14
Метки нет (Все метки)

По совету Stabud создаю тему, в которой будем обсуждать семантику и синтаксис
диалекта FreeBasic.


Вот на такую программу я напоролся, хочется разобраться как работает:

QBasic/QuickBASIC
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
SUB Halve (ByRef i AS INTEGER) 
  i /= 2 
 END SUB 
 
 SUB Triple (ByRef i AS INTEGER) 
  i *= 3 
 END SUB 
 
 TYPE operation AS SUB (ByRef AS INTEGER) 
 
 DIM operations(20) AS operation = _ 
 { @Halve, @Triple, 0 } 
 
 DIM i AS INTEGER = 280 
 
 DIM op AS operation Ptr = @operations(0) 
 WHILE (0 <> *op) 
  (*op)(i) 
  op += 1 
 WEND 
 
 PRINT "Value of 'i' after all operations performed: " & i 
 SLEEP
Мои догадки из другой темы:
Создаются процедуры, создаётся тип - процедура, заводится массив процедур,
сразу присваиваются адреса процедур и нулевой адрес для завершения. Далее создаётся
указатель на массив процедур и вызов процедур по указателю в цикле, пока адрес
процедуры не равен нулю. Т.е в цикле вызываются 2 процедуры с параметром i, сначала
Halve, потом Triple и в итоге i = 420.
Есть подозрение, что я неверно истолковал код, т.к. уже не помню как работает ByRef, если
не ошибаюсь ByVal заталкивает в стек переменную непосредственно, а ByRef заталкивает в
стек адрес переменной, по крайней мере так в досе было.

Вот эта строчка смущает больше всего:
QBasic/QuickBASIC
1
(*op)(i)
Вызываем то, на что указывает op, а он указывает, на нулевой эл-т массива процедур и тут
сразу появляется непонятка, смещаем мы адрес на единицу(на байт т.е.), неужели адрес
процедуры хавает байт? Или каким-то макаром всё таки инкремент индекса получается?
Вот хочется понять, что всё таки в проге происходит.
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.11.2012, 13:28
Ответы с готовыми решениями:

FreeBASIC
Заметил, что уже имеющиеся на форуме темы в разделах: - QBasic - Visual Basic - VBA - Pure...

Осваиваю (ем) FreeBasic
Решил больше не тянуть, а приступить сегодня. Если тема будет актуальна - возможно модераторы...

FreeBASIC и сети
Здравствуй, форум. Всё дело в том, что есть одни сетевые функции, и для этих функций Я решил...

Графика FreeBasic
Приветствую всех cyber-форумчан!:) Несмотря на наличие графического треда в младшем разделе,...

Немного о FreeBasic
Чаще всего при начальном использовании какого-то языка , люди стараются выбрать простую,...

14
stabud
122 / 49 / 1
Регистрация: 26.10.2012
Сообщений: 84
08.11.2012, 14:47 2
Вы практически все правильно поняли, но я распишу все как понимаю для других, кто мало ли заинтересуется

Просто пара процедур, в которые по ссылке
передается переменная i

PureBasic
1
2
3
4
5
6
7
SUB Halve (ByRef i AS INTEGER)
    i /= 2
END SUB
 
SUB Triple (ByRef i AS INTEGER)
    i *= 3
END SUB

Создается\определяется новый тип - указатель на процедуру с одним параметром
Можно было бы обойтись и без этого, но тогда везде придется вместо
operation писать SUB (ByRef AS INTEGER)


PureBasic
1
TYPE operation AS SUB (ByRef AS INTEGER)
создается массив из 21 ячейки 0-20
и заполняются только три ячейки.
Третья заполняется заполняется нулем чисто для понимания.
Все остальные ячейки по умолчанию (автоматически) 3-20 тоже заполняются нулями

PureBasic
1
2
DIM operations(20) AS operation = _
{ @Halve, @Triple, 0 }
просто целочисленная переменная со значением 280

PureBasic
1
DIM i AS INTEGER = 280
Создаем переменную типа двойного указателя (ptr ptr) на процедуру
Даем указание присвоить ему адрес на первую ячейку массива

PureBasic
1
DIM op AS operation Ptr = @operations(0)
Проходим в цикле по массиву, используя смещения адресов,
пока в его ячейке не встретится нуль
Как мы помним, первый нуль находится в третьей ячейке

PureBasic
1
2
3
4
5
6
7
WHILE (0 <> *op) 
    (*op)(i)
    op += 1
Wend
 
PRINT "Value of 'i' after all operations performed: " & i
Sleep
(*op)(i) - это вызов процедуры с параметром.
Поскольку записать так: *op(i) компилятор не позволяет, приходится заворачивать *op в скобки. И только после того, как по адресу (*op) мы получаем адрес вызова процедуры, мы можем ее вызвать с параметром (*op)(i)

С помощью смещения , мы меняем ячейку массива,
и как результат вызываются процедуры Halve и Triple по очереди

Что касается op += 1, то тут важно понимать к какому типу адреса плюсуется
Посмотрите на пример:

PureBasic
1
2
3
4
5
6
7
8
9
'Сейчас указатели равны нулю
Dim iAddr As Integer Ptr 
Dim bAddr As byte Ptr 
Dim dAddr As Double Ptr
 
? dAddr + 1 ' равно 8
? iAddr + 1 ' равно 4
? bAddr + 1 ' равно 1
sleep
1
Quiet Snow
4416 / 1313 / 378
Регистрация: 25.04.2010
Сообщений: 3,409
10.11.2012, 11:07  [ТС] 3
stabud, а можно узнать, где задокументирован такой вызов:
Код
(*op)(i)
хочу почитать об этом побольше: об указателях и о работе с памятью.
Сейчас мутузю справку, но там как-то скудновато расписано или может быть
не вижу просто.
1
stabud
122 / 49 / 1
Регистрация: 26.10.2012
Сообщений: 84
10.11.2012, 12:19 4
Цитата Сообщение от >Quiet Snow< Посмотреть сообщение
stabud, а можно узнать, где задокументирован такой вызов:
Код
(*op)(i)
хочу почитать об этом побольше: об указателях и о работе с памятью.
Именно о таком способе вызове процедур я не помню чтобы где-то было документировано. Может конечно и есть. Я сам это понимаю скажем так сердцем . Возможно что объяснить толком не смог(у).

Про указатели я писал статью в учебнике. Уже читали? Советую потренировать на простых примерах с указателями , хотя бы из того же учебника.

Так же про указатели на оф. сайте в доке И все ссылки на этой странице ниже после See also
1
10.11.2012, 12:19
Quiet Snow
4416 / 1313 / 378
Регистрация: 25.04.2010
Сообщений: 3,409
10.11.2012, 16:24  [ТС] 5
Про указатели я писал статью в учебнике. Уже читали?
Теперь прочитал.

Мда, ну наворотили разрабы с указателями. Да это какой-то паскаль прям, а не бейсик.
С одной стороны хорошо, что столько возможностей, с другой - глядишь на код и пупеешь.
1
locm
10.11.2012, 16:42
  #6

Не по теме:

Цитата Сообщение от >Quiet Snow< Посмотреть сообщение
глядишь на код и пупеешь
Я бы сказал что как будто изучаешь сишный код.

2
stabud
122 / 49 / 1
Регистрация: 26.10.2012
Сообщений: 84
10.11.2012, 20:31 7
Цитата Сообщение от >Quiet Snow< Посмотреть сообщение
Теперь прочитал.

Мда, ну наворотили разрабы с указателями. Да это какой-то паскаль прям, а не бейсик.
С одной стороны хорошо, что столько возможностей, с другой - глядишь на код и пупеешь.
Кликните здесь для просмотра всего текста
Ну дружище, ведь силком никто не заставляет учить FB Не предрасположен к этому языку, что себя насиловать? Есть множество языков (не обязательно васики), выбор велик. Скажу честно, я не испытывал негатив , когда изучал FB, напротив мне было приятно и легко его учить, и теперь комфортно на нем работать. Вам судя по вашим отзывам, он дается с мозолями.
1
Quiet Snow
4416 / 1313 / 378
Регистрация: 25.04.2010
Сообщений: 3,409
11.11.2012, 11:07  [ТС] 8
Не предрасположен к этому языку, что себя насиловать?
Кликните здесь для просмотра всего текста
А может я IT-мазохист Скажу серьёзно:
Если бы не потратил целый год на PB, было бы проще, привык к простоте и элегантности.
Суть в том, что мне от языка не нужно такой кибергибкости, нужны в общем-то банальные
вещи - быстрое 2D(спрайты обычные+альфа, доступ к их памяти), ассемблер, простой обмен
данными по сети и возможность выпустить прогу не получив по башке от правоохранительных
органов. Хочется реализовать идею, а не ковыряться в интерфейсах всю свою жизнь.
Почему трудно, дык я буквально неделю копаюсь, но тем не менее уже портировал несколько
своих прог, непонятки по всем фронтам, вы учили язык знаете. Огорчает меня только один факт
что язык мол есть - он весь такой из себя крутой, но хороших простых примеров раз два и
обчёлся. Если бы не ваш великолепный сайт и советы, то можно было бы вообще на это дело
забивать. Просто я из таких людей, которые не видят смысла усложнять лишний раз, иначе это
становится похожим на соревнования по написанию самого непонятного кода(есть такие).


Не предрасположен к этому языку
Как раз таки наоборот, ближе к QuickBasic ни один язык не подобрался.
Поэтому буду писать в старом стиле, благо разработчики оставили такую возможность.

Добавлено через 1 час 14 минут
Впрочем есть конкреные вопросы:

Оператор Cast ( Тип данных, Выражение )

В справке написано, что он существует для преобразования типов данных.
Непонятен вопрос преобразования к НЕИЗВЕСТНОМУ типу.
Как можно преобразовать если неизвестно, во что преобразовываем?
Что в таких случаях делает компилятор.
1
stabud
122 / 49 / 1
Регистрация: 26.10.2012
Сообщений: 84
11.11.2012, 15:06 9
Цитата Сообщение от >Quiet Snow< Посмотреть сообщение
Впрочем есть конкреные вопросы:

Оператор Cast ( Тип данных, Выражение )

В справке написано, что он существует для преобразования типов данных.
Непонятен вопрос преобразования к НЕИЗВЕСТНОМУ типу.
Как можно преобразовать если неизвестно, во что преобразовываем?
Что в таких случаях делает компилятор.
Оператор CAST предназначен для облегчения работы компилятора. Он может преобразовать данные к любому УКАЗЫВАЕМОМУ типу. Хотя иногда можно вообще не применять его, и на конечное приложение это не повлияет, но на время компиляции повлияет.

PureBasic
1
2
3
4
5
6
7
8
9
10
11
Dim p As Integer Ptr
 
'Просто оставляем на усмотрение компилятора, 
'который конечно сделает все правильно, но выдаст предупреждение
dim i As Integer = p
 
 
'А вот так мы сделаем все правильно и
'поможем компилятору, сократив время компиляции
 
Dim j As Integer =  Cast (Integer, p)
Есть младшие братья CAST , например (CINT, CByte , CShort и пр). Они могут преобразовывать только в определенный тип соответственно вышеописанным (Integer, byte, short)

CAST удобен абсолютно всегда. Например в процедуру передается тип ANY PTR, и вы наверняка знаете что туда будет передаваться указатель на какую-то определенную структуру. В MASM это насколько я помню делалось с помощью ASSUME. В FB просто указываете нужный тип:

PureBasic
1
2
3
4
5
6
7
8
9
10
Type RECT  
    As Long Left 
    As Long top
    As Long Right
    As Long bottom  
End Type
 
Sub A( p As Any Ptr)
    Dim As RECT Ptr NewRECT = Cast ( RECT Ptr , p)
End Sub
И можете дальше легко работать с его полями, не прибегая к средству под названием "смещение".

По "смещение" я имею ввиду:

Запись с относительным безымянным определением адресов отдельных полей:

p+1
p+2
и т. д.

То есть дальше просто:

LEFT = NewRECT->left
RIGHT = NewRECT->right
И т. д.

Надеюсь понятно, но если остались пробелы не стесняйтесь.
1
Quiet Snow
4416 / 1313 / 378
Регистрация: 25.04.2010
Сообщений: 3,409
13.11.2012, 19:04  [ТС] 10
Также вопрос по синтаксису, посмотрел тут по опциям компилятора.
Если указывать вначале проги такую строку:
Код
' $Lang: "FbLite"
То переключается диалект, как будто эту опцию задали в параметрах компилятора.
Так вот понравилось мне, что в поддиалекте FbLite не нужно декларировать переменные,
потому что задирает это до смерти, куча времени спускается на это дело. Так вот вопрос:
подсознательно мне кажется, что эта опция может весьма серьёзно кастрировать диалект
и урезать его возможности, так вот хочу узнать, какие возможности отрезаются.
Вот задался этим вопросом, т.к. пока изучаю, сразу в нужное русло чтобы идти.
0
stabud
122 / 49 / 1
Регистрация: 26.10.2012
Сообщений: 84
13.11.2012, 20:19 11
Цитата Сообщение от >Quiet Snow< Посмотреть сообщение
Так вот вопрос:
подсознательно мне кажется, что эта опция может весьма серьёзно кастрировать диалект
и урезать его возможности, так вот хочу узнать, какие возможности отрезаются.
Кликните здесь для просмотра всего текста
Тут наверно смогут ответить только те, кто не по наслышке знаком с исходниками FB. Я могу лишь подозревать , что могут быть проблемы с подключением сторонних библиотек. Я вообще не сторонник этих антикварных возможностей, связанных со старыми диалектами. Одно дело что-то путное из старья скомпилить с учетом этих макросов , и другое дело писать в том стиле.

Если уж так задирает писать такие фразы:

Dim i as Integer

Можно же сокращать (то есть объявлять сразу по нескольку):

Dim as Integer i , j, a, b, c, d

Или тот же оператор VAR (три буквы уж не переломит написать):

Var s = "Это строка", d = 56.456
1
locm
13.11.2012, 20:31
  #12

Не по теме:

Цитата Сообщение от >Quiet Snow< Посмотреть сообщение
не нужно декларировать переменные
Это допустимо только для простых проектов.
Практика показывает что при этом легко допустить ошибку в имени переменной и потом гадай почему прога работает не так, как задумано.
Я обычно при создании программ, указываю компилятору чтобы он сообщал об ошибке когда в коде встретится не объявленная переменная.

1
Quiet Snow
4416 / 1313 / 378
Регистрация: 25.04.2010
Сообщений: 3,409
13.11.2012, 21:34  [ТС] 13
Одно дело что-то путное из старья скомпилить с учетом этих макросов , и другое дело писать в том стиле.
Ну как я понял для старья существует опция QB с помощью которой я портирую проги с QuickBasic,
а вот FbLite это что-то типа облегчённой версии Fb и к антиквариату вроде не относится.
Суть не в том, что сложно объявлять, чисто вопрос удобства и времени(ни VAR ни сокращённый DIM
от его потери в огромных кол-вах не спасут, да и идеи по алгоритму теряются частенько из-за этого),
всё таки это ключевая и очень аппетитная особенность бейсиков, машинную работу пусть делает
машина, ну это имхо конечно.

Я могу лишь подозревать , что могут быть проблемы с подключением сторонних библиотек.
У меня тоже предчувствие есть, что с библиотеками может "ласосинг" случиться...
Пока правда всё ok, но вот терзают смутные сомнения, что какие-либо языковые средства, которые
есть в Fb, в FbLite не сработают, часто пишется в справке внизу конкретных функций, но вот
суммарно бы про это почитать.

Добавлено через 21 минуту
to locm:
Практика показывает что при этом легко допустить ошибку в имени переменной
про объявление переменных
Давно уже не ловил такие простые ошибки, дело привычки. Да и стараюсь не расшаривать
часто используемые переменные, чтобы не поймать баг. Пользуюсь венгерской нотацией в
немного урезанном варианте, да и если понимаю, что есть реальная возможность получить
пересечение переменных, подбираю имена, которые 100% не встретятся.

Не от вас первого слышу такое мнение, но с ним я не согласен. На самом деле, если над программой
работает 1 человек, шанс допустить ошибку крайне мал, в крупном проекте с несколькими людьми
это скорее необходимость, да и на Fb вряд ли будут такие проекты, с кучей кодеров. Модульное
программирование отчасти решает этот вопрос, изолируя требуемые области, получить доступ к ним
можно, только если специально расшаривать.
1
locm
13.11.2012, 21:59
  #14

Не по теме:

Цитата Сообщение от >Quiet Snow< Посмотреть сообщение
Давно уже не ловил такие простые ошибки
Вы меня не так поняли.
Я имел в виду что без обязательной декларации переменных, легко допустить ошибку в имени переменной, скажем, имеем переменную с именем MyVar и набирая ее имя к коде, случайно на клавиатуре набрали MuVar. Компилятор это схавал и мы думаем почему же прога работает не так как запланировано. Может ошибка в алгоритме? Долго ее имем и наконец, матерясь, обнаруживаем что всему виной ошибка в имени переменной.

2
Quiet Snow
4416 / 1313 / 378
Регистрация: 25.04.2010
Сообщений: 3,409
14.11.2012, 00:10  [ТС] 15
Вы меня не так поняли.

Не по теме:

locm, об этом можно долго рассуждать, я понял ваши мысли, просто мне реально удобнее
так, кто бы чего не говорил. Тем более, что этих ошибок не допускаю(всегда через копирование).



Добавлено через 1 час 8 минут
У меня тоже предчувствие есть, что с библиотеками может "ласосинг" случиться...
Да я был прав, фигня с библиотеками, т.к. если опция $Lang: "FbLite" включена компилятор даже то,
что выше этой директивы обрабатывает по принципу другого диалекта. Но сразу скажу - лечится.
Лечится элементарно, создаём из кода статическую библиотеку в режиме компиляции Fb и подключаем
её к коду в котором уже пишем на FbLite, естественно все декларации и хедеры не забываем.
Так что всё очень даже юзабельно.
1
14.11.2012, 00:10
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
14.11.2012, 00:10

Задача на графику в FreeBASIC
Помогите с задача по графике в FreeBASIC Построить совокупность n равных отрезков, центры которых...

FreeBasic круги на воде
Очень интересный код имитирующий распространение кругов на воде. Описание алгоритма тут Что меня...

FreeBasic. MyFbFramework + VisualFBEditor
Начал новый фреймворк для FreeBasic: MyFbFramework И редактор для него: VisualFBEditor Файлы...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru