С++ язык со строгой типизацией. Это означает, что каждая переменная чётко определена для хранения конкретного типа данных и ничего другого в неё положить нельзя.
Возможно, это не даёт такого удобства в написании программы, как изменение данных в переменной на лету, но с другой - избавляет вас от постоянного поиска ошибок из-за несовпадения типов данных (ожидаемого и фактического).
Рассмотрим пример:
Возможно, это не даёт такого удобства в написании программы, как изменение данных в переменной на лету, но с другой - избавляет вас от постоянного поиска ошибок из-за несовпадения типов данных (ожидаемого и фактического).
Рассмотрим пример:
int a = 2;
Это целочисленная переменная. Попытка записать в неё строку приведёт к ошибке. Вы всегда можете быть уверены, что в этой переменной лежит целое число.
В языках без строгой типизации вы вполне можете записать в одну и ту же переменную сначала целое число, потом дробное, а позже - строку. А потом, передавая эту переменную в функцию, которая выполняет математические операции, вы не будете понимать, почему программа не работает. До тех пор, пока не отследите, что вы в эту функцию передали текст.
Поэтому лично я не склонен называть строгую типизацию - минусом. Да, иногда вам придётся объявлять больше переменных, чем могло бы понадобиться для работы, но зато проблема несовпадения типов у вас отсутствует как класс.
В языках без строгой типизации вы вполне можете записать в одну и ту же переменную сначала целое число, потом дробное, а позже - строку. А потом, передавая эту переменную в функцию, которая выполняет математические операции, вы не будете понимать, почему программа не работает. До тех пор, пока не отследите, что вы в эту функцию передали текст.
Поэтому лично я не склонен называть строгую типизацию - минусом. Да, иногда вам придётся объявлять больше переменных, чем могло бы понадобиться для работы, но зато проблема несовпадения типов у вас отсутствует как класс.
Приведение типов
В Корсарах наряду с базовыми типами С++ есть и свои собственные. Базовые в скриптах представлены далеко не все, однако основные есть и для работы этого достаточно.
int - целое число (сокр. от «integer»).
Может хранить целые числа (без дробной части), включая отрицательные.
Может хранить целые числа (без дробной части), включая отрицательные.
int a = 12;
int b = -4;
float - число с плавающей запятой.
Хранит десятичные дроби, включая отрицательные.
Хранит десятичные дроби, включая отрицательные.
float x = 12.58;
float y = -3.00;
string - строка.
Хранит текст. Присваиваемые значения всегда должны быть заключены в кавычки, даже если строка пустая.
Хранит текст. Присваиваемые значения всегда должны быть заключены в кавычки, даже если строка пустая.
string s = "";
string t = "мама мыла раму";
Сложение строк («конкатенация») производится при помощи оператора +.
Перенос текста на новую строку осуществляется при помощи конструкции \n. В некоторых случаях, вместо \n необходимо использовать функцию NewStr().
Перенос текста на новую строку осуществляется при помощи конструкции \n. В некоторых случаях, вместо \n необходимо использовать функцию NewStr().
string m = "Вот это первая строка\nА это уже вторая";
string n = "Вот это первая строка" + NewStr() + "А это уже вторая";
Альтернативного варианта записи строки не существует. Поэтому вместо двойных кавычек внутри строки используются одинарные.
string g = "Табличка 'Таверна' висела прямо на уровне глаз.";
bool - логический тип данных.
Может принимать значения true и false.
Технически bool это целое число, где 1 равна значению true, а 0 == false.
Может принимать значения true и false.
Технически bool это целое число, где 1 равна значению true, а 0 == false.
bool b = false;
bool d = 1; // true
Существуют некоторые особенности использования целого числа как типа bool:
int a;
if (a == true) {} // при таком обращении 1 возвращает true, а все остальные числа - false
if (a) {} // а при таком - 0 возвращает false, a все остальные числа true
Цитата Rosarak:
Никогда не используйте тип данных float в качестве значений для bool'ов.
В ходе неявного преобразования типов значение 0.9 превратится в 0 и засчитается как false.
void - прямой перевод - «пустота», означает отсутствие любого типа данных.
В пределах скриптов Корсаров используется только для обозначения функции, которая не возвращает данных.
Объявить переменную с типом void нельзя.
В пределах скриптов Корсаров используется только для обозначения функции, которая не возвращает данных.
Объявить переменную с типом void нельзя.
void myFunc()
{
// ...
}
object - объект (древовидная текстовая структура).
Здесь стоит остановиться подробнее. Как я говорил в самом начале - ООП в скриптах не доступно. Тем не менее, разработчики предоставили возможность создавать структуры, которые заменяют нам объекты классов.
Важно помнить, что все значения в таких структурах хранятся в виде строк (string).
Учиться работать с объектами и ссылками на них мы будем в отдельном уроке. //
Здесь стоит остановиться подробнее. Как я говорил в самом начале - ООП в скриптах не доступно. Тем не менее, разработчики предоставили возможность создавать структуры, которые заменяют нам объекты классов.
Важно помнить, что все значения в таких структурах хранятся в виде строк (string).
Учиться работать с объектами и ссылками на них мы будем в отдельном уроке. //
object Cannon[CANNON_TYPES_QUANTITY];
ref - ссылка на объект (сокр. от «reference»).
Используется для обращения к структурам object. Сама ссылка создаётся при помощи функции:
Используется для обращения к структурам object. Сама ссылка создаётся при помощи функции:
object Items[ITEMS_QUANTITY];
ref itm;
makeref(itm, Items[n]);
aref - ссылка на атрибут объекта (сокр. от «attribute reference»).
Так как ваша структура object может быть любой - обращение к данным может быть очень длинным, составляя десятки слов и это не очень удобно, не говоря уже о том, что нечитабельно. Для этого используются ссылки на конкретные атрибуты объекта. Принцип такой же, как и в предыдущем типе:
Так как ваша структура object может быть любой - обращение к данным может быть очень длинным, составляя десятки слов и это не очень удобно, не говоря уже о том, что нечитабельно. Для этого используются ссылки на конкретные атрибуты объекта. Принцип такой же, как и в предыдущем типе:
object Items[ITEMS_QUANTITY];
ref itm;
aref arItm;
makeref(itm, Items[n]);
itm.id = "patent_eng";
itm.type.arm = true;
makearef(arItm, itm.type);
if (sti(arItm.arm) == true)
{
// ...
}
Преобразование типов
Выше я сказал, что все структуры хранят данные в виде строк. Но как же тогда работать со здоровьем персонажа, скоростью корабля и т.д.?
Для этого существуют встроенные функции, которые преобразовывают один тип данных в другой.
Для этого существуют встроенные функции, которые преобразовывают один тип данных в другой.
MakeInt - преобразование в целое число. Может принимать строку или число с плавающей точкой.
// синтаксис
int MakeInt(string value);
int MakeInt(float value);
// пример
int a;
a = MakeInt("33");
a = MakeInt(0.8);
MakeFloat - преобразование в число с плавающей точкой. Может принимать строку или целое число.
// синтаксис
float MakeFloat(string value);
float MakeFloat(int value);
// пример
float x;
x = MakeFloat("3.12");
x = MakeFloat(10);
sti - преобразование строки в целое число (сокр. от «string to integer»). В качестве аргумента принимает строку.
// синтаксис
int sti(string value);
// пример
int a = sti("4");
stf - преобразование строки в число с плавающей точкой (сокр. от «string to float»).
// синтаксис
float stf(string value);
// пример
float y = stf("12.44");
fts - преобразование числа с плавающей точкой в строку (сокр. от «float to string»). Принимает число с плавающей точкой, которое нужно преобразовать, а также количество цифр после запятой, которые будут сохранены.
// синтаксис
string fts(float value, int digits);
// пример
float pi = 3.141526535;
string s = fts(pi, 3); // 3.14
string d = fts(pi, 5); // 3.1415
Вообще, движок поддерживает прямое присвоение числа в строку:
int num = 12;
string s;
s = num; // "12"
Но с числами типа float есть нюансы.
Цитата Rosarak:
ОСОБЕННОСТЬ прямое присвоение строке чисел с плавающей запятой добавляет неожиданную дробную часть. Необходимо использовать специальные функции типа fts() или конструкцию вида s = "" + ffloat f = 1.2; string s; s = f; log_info(s); // "1.200000007" s = "" + f; log_info(s); // "1.2"
argb - сохраняет код цвета ARGB в виде целого числа в шестнадцатеричном формате. Аргументы: a - альфа-канал (0-255), r - красный (0-255), g - зелёный (0-255), b - синий (0-255).
// синтаксис
int argb(int a, int r, int g, int b);
// пример
int color = argb(255, 10, 10, 10); // 0xAARRGGBB
Ред. avuremybe
Исправлю))
А тест в игре показал, что -1 даёт false.
Здесь очень много особенностей, и порой они обескураживают.
Ред. nazarpunk
В имеющихся в игре текстах везде используются одинарные. Полагаю, этому есть очень простое объяснение...
Ред. ScorpioT1000
Крч это для имитации обращения к экземпляру класса.
Ред. avuremybe
Уверее, что работать это не будет, интересно только как именно.
Из-за того, что нормальной компиляции нет, такие вещи могут вести себя очень непредсказуемо. Например выполнится до первой кавычки и отвалится до конца блока кода. А дальше опять всё будет выполняться
Ред. ScorpioT1000
Ред. ScorpioT1000
Вот есть наглядная картинка по распределению точности. Чем дальше от нуля, тем для больших диапазонов будет одинаковое число возможных значений