]>Секреты и хитрости программирования на FreeBASIC'е

Секреты и хитрости программирования на FreeBASIC'е

Аватар пользователя mabu

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

  1. Общие оптимизации
    1. Функция Iif
    2. Обмен значениями двух переменных без использования третьей
    3. Получение символа в строке
    4. Посимвольный обход строки
    5. Используй оператор Const как можно чаще
    6. Преобразование строк в кодировку UTF-8 и обратно
  2. Уменьшение размера исполняемого файла
    1. Прекращение инициализации переменных по умолчанию
    2. Использование строковых констант
    3. Быстрая очистка (обнуление) строки

Общие оптимизации

Функция Iif

Часто бывает целесообразным заменить блок IfThenElse более компактной функцией Iif:

Код FreeBASIC
' Длинный код
If a >= 3 Then
    b = 4
Else
    b = 5
End If

' Короткий код
b = Iif(a >= 3, 4, 5)

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

Пусть даны две переменные x и y. Необходимо обменять значения переменных не используя третью.

Первый вариант:

Код FreeBASIC
x = x + y
y = x – y
x = x – y

Второй вариант:

Код FreeBASIC
x = x Xor y
y = y Xor x
x = x Xor y

Получение символа в строке

Новички нередко используют функцию Mid для получения единственного символа в строке, однако есть способ проще.

Строка — это массив символов, следовательно, к ней можно применять индексирование по указателю.

Код FreeBASIC
' Строка длиной в 99 символов (+1 на нулевой)
Dim s As WString * (99 + 1)
' Получение первого символа в строке
Dim Char As Integer = s[0]

Посимвольный обход строки

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

Код FreeBASIC
Dim s As WString * (99 + 1) = Any
s = "Привет, мир!"
Dim i As Integer = 0
Do Until s[i] = 0
&t;' Вывести код символа
&t;Print s[i]
&t;i += 1
Loop

Если заранее известно, что строки будут ненулевой длины, то условие выхода из цикла Until s[i] = 0 можно поставить после Loop. Это уберёт двойной прыжок для нулевого символа.

Используй оператор Const как можно чаще

Замечательное свойство оператора Const состоит в том, что он накладывает определённое ограничение: данный объект не должен модифицироваться, – и компилятор будет проводить это ограничение в жизнь. Const позволяет указать компилятору и программистам, что определённая величина должна оставаться неизменной. Во всех подобных случаях необходимо обозначать это явным образом, призывая себе на помощь компилятор и гарантируя тем самым, что ограничение не будет нарушено.

Во‐вторых, константы убирают из кода «магические числа». Такое число само по себе не несёт никакого смысла и может вызвать недоумение, встретившись в коде программы без соответствующего контекста или комментария, при этом попытка изменить его на другое, даже близкое по значению, может привести к абсолютно непредсказуемым последствиям. Магическими числа — плохая практика программирования, когда в исходном тексте встречается числовое значение и неочевидно, что оно означает. Например, такой фрагмент будет плохим:

Код FreeBASIC
DrawSprite(53, 320, 240)

Человеку, который не является автором программы, трудно сказать, что такое 53, 320 или 240. Но если этот код переписать, всё становится на свои места:

Код FreeBASIC
Const SCREEN_WIDTH As Integer = 640
Const SCREEN_HEIGHT As Integer = 480
Const SCREEN_X_CENTER As Integer = SCREEN_WIDTH \ 2
Const SCREEN_Y_CENTER As Integer = SCREEN_HEIGHT \ 2
Const SPRITE_CROSSHAIR As Integer = 53

DrawSprite(SPRITE_CROSSHAIR, SCREEN_X_CENTER, SCREEN_Y_CENTER)

Кроме того, магические числа — потенциальный источник ошибок в программе:

Преобразование строк в кодировку UTF-8 и обратно

В библиотеке kernel32.dll уже реализованы специальные функции. Достаточно подключить заголовочный файл windows.bi.

Перекодировать строку в UTF-8

Задача: Имеется строка (в юникоде), её необходимо перекодировать в UTF-8.

Подойдёт функция WideCharToMultiByte:

Код FreeBASIC
' Размер буфера
Const BufferLength As Integer = 10 * 1024
' Строка в юникоде для ковертации
Const Utf16 = "Привет, мир!"
' Строка в UTF-8
Dim Utf8 As ZString * (BufferLength + 1) = Any
' Выполнить
Dim CharsCount As Integer = WideCharToMultiByte(CP_UTF8, 0, @Utf16, -1, @Utf8, BufferLength, 0, 0)

Функция возвращает количество записанных символов вместе с завершающим нулём.

Перекодировать UTF-8 в строку

Задача: имеется строка в кодировке UTF-8, её нужно перекодировать в юникодную фрибейсиковую строку.

Подойдёт функция MultiByteToWideChar:

Код FreeBASIC
' Строка Utf8 где‐то объявлена и содержит данные
Dim Utf16 As WString * (BufferLength + 1) = Any
Dim CharsCount As Integer = MultiByteToWideChar(CP_UTF8, 0, @Utf8, -1, @Utf16, BufferLength)

Функция возвращает количество записанных символов вместе с завершающим нулём.

Примечание: во избежание нарушений доступа строка Utf8 должна заканчиваться нулём.

Уменьшение размера исполняемого файла

Прекращение инициализации переменных по умолчанию

При объявлении новой переменной ей сразу же присваивается значение по умолчанию, если мы не сделали это сами. Например, целочисленным переменным присваивается значение 0, строки неизменяемой длины ZString и WString заполняются нулями на всю их длину. Если нам не требуется инициализация переменных, для этого переменной нужно присвоить специальное значение Any.

Код FreeBASIC
' После этого в переменной Count содержится мусор:
Dim Count As Integer = Any

Dim Value As WString * BufferSize = Any
' Чтобы строка оставалась валидной, ей нужно добавить нулевой символ
Value[0] = 0

Использование строковых констант

Необходимо использовать строковые константы везде (желательно в заголовочных файлах). Это исключает дублирование. Все строковые константы хранятся в секции .data. При использовании строковых литералов прямо в коде высока вероятность повторения одних и тех же данных несколько раз, что увеличит размер секции .data.

Код FreeBASIC
Const MyConst = "Это константа"

Компилятор сам определит тип строки: юникодная WString или простая ZString на основании определения #define unicode.

Быстрая очистка (обнуление) строки

Для этого достаточно присвоить 0 первому символу в строке, то есть символу под индексом 0:

Код FreeBASIC
Dim Value As WString * BufferSize = Any
Value[0] = 0

Поделись ссылочкой в социальных сетях