Структуры

В этой статье, мы рассмотрим структуры. В отличии от массивов у структур нет индексов, вместо них выступают имена ее полей. Ее главное отличие, нужное нам, это возможность хранить разные типы данных и создавать свои типы. Структура как и массив-это длинная вереница байт, идущих друг за другом. Это свойство, позволяет обращаться к частям структуры или массива разными, удобными нам способами. Стоит отметить, что структуры даже в большей степени чем массивы, используются функциями API, которых в системе Windows насчитывается несколько тысяч в разных библиотеках файлов DLL.  И без которых, разработка приятного нам оконного интерфейса, станет затруднительной. В том числе именно поэтому, необходимо уметь пользоваться этим  инструментом.
Начнем с определения своего типа данных. Для того, чтобы определить новый тип данных, кроме имеющихся (Byte, String, Integer и прочие...), нужно воспользоваться командой Type

Type Char As String*1

Вот таким способом, мы объявили новый тип CHAR , который будет вмещать лишь один строковой символ. Данный тип широко используется в других распространенных языках программирования, и объявление различных типов, может упростить перенос каких то наработок с других языков. Как видите, объявление нового типа данных, очень схоже с объявлением переменных. Первой идет команда Type , далее сам новый тип и за ключевой командой As идет определяемый ему тип. А теперь пример:

Type char As String*1
Dim simvol As CHAR
simvol="ABC"
? Simvol
Sleep

Я намеренно в переменную с новым типом заношу значение из трех символов. Конечно же в ней окажется только буква "А". Ведь у нас новый тип имеет свойства вмещать только один символ. Вы можете поэкспериментировать с этим примером.... Вот мы и подобрались к определению самих структур. Основное что требуется понять, это то что создание простейшей структуры как минимум делится на два важных действия со стороны программиста:

  • Создание шаблона структуры
  • Объявление переменной, которая имеет тип и свойства шаблонной структуры

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

Type Persons
    
End Type

А теперь реальный пример и после разжуем его:

Type Persons
    Name As String
    Surname As String
    Age As Byte = 35
End Type

Dim Vpersons As Persons

Vpersons.Name="Richard"
Vpersons.Surname="Black"

? Vpersons.Name
? Vpersons.Surname
? Vpersons.Age
Sleep

В этом примере мы определили шаблонную структуру Persons с тремя полями. Два поля (Name и Surname), которым мы задали строковые типы и одно поле (Age) с байтовым типом. Последнему кстати, мы присвоили значение по умолчанию. По своей сути мы создали шаблон, по которому будут создаваться переменные с этим типом. То есть если немного упрощенно, когда мы создали переменную Dim Vpersons As Persons , мы дали понять компьютеру, что требуется выделить память в каком нибудь свободном месте, для нашей переменной Vpersons в размере, который соответствует размеру Persons. В итоге наша переменная имеет тот же размер, и еще в нашем случае, в одном из полей присвоено значение 35. Это свойство широко используется в многозадачной системе Windows. Полям структуры необходимо задавать тип и необязательно задавать значения. Для того чтобы задать тип полей, использовать команду Dim не нужно. Но при объявлении новой переменной с типом нашей структуры , без команды Dim не обойтись . Как вы заметили, делается это так же, как при объявлении обычных переменных, только вместо стандартных типов(string ,integer и других) используется имя нашей шаблонной структуры . А далее переменная, имеющая такие же поля, как и у самой структуры, может использоваться нами для того, чтобы считывать оттуда значения , или же записывать туда новые значения.Определять однотипные поля структуры можно и в одну строку, так же как с обычными переменными:

Type Persons
    As String   Name , Surname
End Type

Обращение к полям структуры возможно напрямую или через указатель. Вот запись обращается к полю структуры напрямую через точку:

Vpersons.Age

А такая через указатель:

Vpersons -> Age


В принципе нет ничего сложного:

Для обращения к любому из полей, нужно записать имя структурной переменной и через точку имя соответствующего поля.

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

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

Type Base_1
    As Integer x=5,y=2,z=8
End Type

Dim As Base_1 A,B,C

C.x=25

Print A.x , A.y , A.z
Print B.x + B.y + B.z
Print C.x , C.y , C.z
Sleep

До этого мы создавали простейшие структуры. Но в программировании на многих языках и в том числе FreeBasic, есть такое понятие как вложенные структуры. То есть как бы в одной находятся несколько. Конечно вот такую запись вам компилятор сделать не позволит:

Ошибка

Хотя есть структуры с названием Union, которые можно так записывать. Обычные вложенные структуры, записываются несколько другим способом:

 Пример:

Type Base_2
    As Integer x=5,y=2,z=8
End Type

Type Base_1
    Base_2 As Base_2
    B As String="Hello"
End Type

Dim As Base_1 A

Print A.Base_2.x , A.Base_2.y ,A.Base_2.z , A.B
Sleep

Здесь структура  Base_2 вложена в структуру Base_1. Первый блок структуры должен быть понятен. Что касается второго, то в нем два поля: 

1)  структурированная переменная
2)  обычная строковая

Но мы должны понимать, что обе эти переменные принадлежат другой структурированной переменной 'A' Для указания строковой(не вложенной), как и в примерах выше, достаточно  имени 'A' и названия поля 'B'  в итоге 'A.B'

Что же касается других полей, то они принадлежат своей структурированной переменной с именем Base_2. Поэтому нам нужен допуск к ее полям через ее имя. A.Base_2.x  

Или, как может кто войти в дом сильного и расхитить вещи его, если прежде не свяжет сильного? и тогда расхитит дом его...

Представьте себе вложенные структуры как несколько дверей.Для того, чтобы добраться до переменных X или Y или Z ,  нам нужно открыть две двери по очереди. Вообще вложенных структур в языке FreeBasic может столько, сколько вам требуется.

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

А если все в порядке, то давайте продолжим. Массивы и структуры очень часто используют вместе (тандемом). По сути для некоторых задач один инструмент будет дополнять другой.  Давайте посмотрим на примере:

Type Base_0
    a As Integer=16
End Type

Dim As Base_0  array(10)

Print array(5).a
Sleep

По своей сути тоже самое, что и с простой переменной, просто у массива еще в скобках указывается индекс. Чем хорошо использование массива со структурами? Как известно массивы могут хранить только однотипные данные. С помощью структур, мы можем хранить в массиве разнородные данные, которые описываются в структуре. Ведь мы не нарушаем правила синтаксиса. Мы записываем в массив все так же один тип; тип нашей структуры. А уж то, что мы в эту структуру напехаем, на это массиву ровно "пофиалетово". Ему то предлагается для ячеек один и тот же размер; размер структуры, который кстати сказать определяется суммой всех ее полей.

А теперь я ниже написал пример простого автомата, который спрашивает имя, фамилию и профессию. Проделывает он это 3 раза, а потом выводит на экран консоли результаты. Вам встретится новая команда CLS. Это графическая команда. Используется для очистки экрана. Остальное все вам должно быть знакомо.

Type Base_0
    As String Name
    As String Surname
    As String Profession
End Type

Dim As Base_0 B(2)

For a As Integer=0 To 2
    Input "Enter Name: ",B(a).Name
    Input "Enter Surname: ",B(a).Surname
    Input "Enter Profession: ",B(a).Profession
    Cls  ' Очищаем экран
Next
Print "Name" , "Surname" , "Profession"
Print
For a As Integer = 0 To 2
    Print B(a).Name , B(a).Surname , B(a).Profession
Next
Sleep

Сначала мы создали структуру Base_0 из трех строковых полей. Далее мы объявили структурированный массив с именем B  и типом Base_0. Затем мы заводим цикл на три итерации и в нем ждем ввода от пользователя с помощью команды input, при этом каждый раз сохраняя результаты ввода в структурированном массиве. И конечно после того, как вводятся данные на одного человека, очищаем экран консоли. Всего в нашей базе должно быть три человека. Далее с помощью команд Print , мы выводим надпись и пустую строку. А затем той же командой Print печатаем в цикле считываемые данные из структурированного массива.  Надеюсь понятно.

В синтаксисе FreeBasic есть блок With - End With , который позволяет обращаться к полям структуры без имени . Очень часто это бывает полезно. Посмотрите на пример:

Type Base_
    As String Name
    As String Surname
    As String Profession
End Type

Dim As Base_ My_base

With My_base
    .Name="Tom"
    .Surname="Razen"
    .Profession="Designer"
End With
? My_base.Name
Sleep

Как видите имя нашей структурированной переменной пишется после ключевого слова With .  А в самом блоке пишется только точка с именами полей. Но отдельно от блока имя писать надо, что я и показал в предпоследней строке.

В FreeBasic есть еще специальный блок структур с названием Union - End Union. Это некий объединяющий в одну переменную блок, который может в своем теле содержать различные типы данных, имеющих определяемую длину. То есть в блок нельзя записать строковую переменную обычным образом: 

value As String

Но если указать длину этой переменной , то проблем не будет:

value As String*19

Его основное назначение-это иметь одну общую переменную с разными типами в одном месте памяти. Размер этой переменной берется по максимальной переменной. Пример:

Union Un
    a As Byte
    b As Short
    c As Integer
End Union

Dim value As Un
value.a=16
? value.b
? value.c
Sleep

Структурированная переменная value заняла в памяти только 4 байта (Integer самая большая). Примечание: на 32-bit системе размер Integer = 4 байта , на 64-bit системе Integer = 8 байтам. Соответственно и переменная value будет иметь разный размер на системах разной разрядности.  Но в любой момент мы можем не преобразовывая специальными функциями, иметь число (в данном случае 16) с типом Byte , Short , Integer. Для этого просто надо обращаться к нужному полю структуры. Чуть выше я писал о том, что в обычных структурах можно записывать структуры Union. Вообще их можно записывать не только вовнутрь структур, но и в функции, процедуры, и в специальные функции классов. Единственно, записывая внутрь структур, имя Union уже указывать не надо, она принадлежит структуре. Пример:

Type Data_
    Union
        a As Byte
        b As Short
        c As Integer
    End Union
End Type
Dim value As Data_
value.a=16
? value.b
? value.c
Sleep

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

содержание | назад | вперед