![]() |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Простые типы данных Переменные и константы
Отметим, что термин объявление означает только указание, каким образом объявляемое имя будет интерпретироваться компилятором. do { char char1 = _getch();
Если имя или выражение означает переменную или значение простого типа, тогда тип этой переменной или значения называется типом имени или выражения.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
char signed char |
Символьный тип. Диапазон значений от -128 до 127. |
unsigned char |
Символьный тип. Диапазон значений от 0 до 255. |
short |
Целый тип. Диапазон значений от -32768 до 32767. |
unsigned short |
Беззнаковый целый тип. Диапазон значений от 0 до 65535. |
int |
Целый тип. Диапазон значений от -2147483648 до 2147483647. |
unsigned int |
Беззнаковый целый тип. Диапазон значений от 0 до 4294967259. |
__intn |
Целый тип, размер в битах которого определяется значением n, и может быть равным 8, 16, 32 или 64 битам. |
long |
Целый тип. Диапазон значений от -2147483648 до 2147483647. |
unsigned long |
Беззнаковый целый тип. Диапазон значений от 0 до 4294967259 |
float |
Тип данных с плавающей точкой. Диапазон значений от 3.4Е-38 до 3.4Е+38. |
double |
Тип данных с плавающей точкой двойной точности. Диапазон значений от 1.7Е-308 до 1.7Е+308. |
long double |
Тип данных с плавающей точкой двойной точности, длина которого равна длине значений типа double. |
Размер памяти, выделяемой под каждый тип данных языка C\C++, в некотором смысле зависит от используемой платформы и компилятора. Однако все компиляторы гарантируют, что для типа short памяти всегда выделяется меньше или столько же, сколько и для типа int, а тип long всегда "длиннее" или равен типу int.
Символьные типы char и unsigned char представляют значение символа, реализуемое одним байтом. Для использования символов в кодировке Unicode язык C++ предоставляет тип wchar_t, в котором под каждый символ отводятся два байта.
Ключевое слово typedef языка C++ позволяет объявить новое имя существующего типа.
Например:
typedef int my_integer;
my_integer i1=0;
Создание псевдонима для типа значительно облегчает процесс изменения типа переменных в уже отлаженном коде.
Символьным литералом или символьной константой называется символ, заключенный в одинарные кавычки. Целые литералы представляют целочисленные константы в десятичном, восьмеричном или шестнадцатеричном виде.
Восьмеричные литералы начинаются с символа 0, а шестнадцатеричные - с символов 0x.
После литерала может быть указан суффикс, определяющий его тип: U - unsigned int, L - long int.
Например:
00 // Восьмеричное значение, равное 0
oxffff // Шестнадцатеричное значение,
// равное 65535
10L // Значение типа long int
При записи шестнадцатеричных литералов каждый знак может принимать значение от 0 до 15. Для записи значений от 10 до 15 принято использовать следующие символы: a - 10, b - 11, c - 12, d - 13, e - 14 и f - 15.
Литералы с плавающей точкой могут записываться в двух формах: вещественной и экспоненциальной.
Например:
1.53
32.24e-12
// Экспоненциальная форма записи литерала
Литералы с плавающей точкой могут использоваться для инициализации значений переменных вещественного типа (float, double или long double).
Язык C++ позволяет выполнять преобразование значения одного типа в значение другого типа. Преобразование типа может быть явным и неявным. Явное преобразование называется приведением типов.
Для явного приведения типов можно использовать две формы записи:
Например:
std::cout <<"strlen="<<(long)strlen(pArr1);
Например:
std::cout <<"strlen="<<static_cast<long>(
strlen(pArr2));
Вторая форма явного преобразования типов более предпочтительна, поскольку несет в себе дополнительную информацию, позволяющую сократить число возможных ошибок.
Дополнительная информация о приводимом типе может быть указана следующими операторами:
Преобразование типов выполняется для значений переменных при вычислении выражений и оказывает влияние на тип результата. Преобразование типов не изменяет типа самих переменных, участвующих в выражении.
Типы данных языка Object Pascal
Все переменные и константы, используемые в программе, всегда принадлежат какому-либо типу. Вызов функции также возвращает значение определенного типа.
Типы данных языка Object Pascal можно разбить на следующие группы:
В язык Object Pascal включены следующие базовые типы данных:
Тип |
Диапазон значений |
Формат |
Integer |
-2147483648..2147483647 |
signed 32-bit |
Cardinal |
0..4294967295 |
unsigned 32-bit |
Shortint |
-128..127 |
signed 8-bit |
Smallint |
-32768..32767 |
signed 16-bit |
Longint |
-2147483648..2147483647 |
signed 32-bit |
Int64 |
-263..263-1 |
signed 64-bit |
Byte |
0..255 |
unsigned 8-bit |
Word |
0..65535 |
unsigned 16-bit |
Longword |
0..4294967295 |
unsigned 32-bit |
Тип |
Диапазон значений |
Размер в байтах |
Real |
5.0 * 10-324 .. 1.7 * 10308 |
8 |
Real48 |
2.9 * 10-39 .. 1.7 * 1038 |
6 |
Single |
1.5 * 10-45 .. 3.4 * 1038 |
4 |
Double |
5.0 * 10-324 .. 1.7 * 10308 |
8 |
Extended |
3.6 * 10-4951 .. 1.1 * 104932 |
10 |
Comp |
-263+1 .. 263 -1 |
8 |
Currency |
-922337203685477.5808.. 922337203685477.5807 |
8 |
Тип |
Диапазон значений |
Размер в байтах |
Boolean |
True или False |
1 |
ByteBool |
True или False |
1 |
WordBool |
True или False |
2 |
LongBool |
True или False |
4 |
Тип |
Диапазон значений |
Размер в байтах |
Char |
ANSI-символ |
1 |
AnsiChar |
ANSI-символ |
1 |
WideChar |
Unicode-символ |
2 |
Тип |
Максимальная длина |
Размер в байтах |
string |
Определяется директивой компилятора $H |
|
ShortString |
255 символов |
От 2 до 256 байт |
AnsiString (длинная строка) |
~231 символов |
От 4 байт до 2 Гбайт |
WideString (Символы Unicode) |
~230 символов |
От 4 байт до 2 Гбайт |
Для строковых переменных выполняются следующие правила:
Например:
var
S1: string;
{Объявление строковой переменной
произвольной длины}
S2: string[2];
{Объявление строковой переменной
длиной 2 символа}
Строки типа AnsiString также называют длинными строками (long string), представляющими динамически размещаемые строки, длина которых ограничена только доступной памятью. Такие строки используют 1-байтовое представление ANSI-символов.
Реально переменная типа AnsiString является указателем, состоящим из 4 байт. Если строка пустая (ее длина равна 0), то указатель равен nil и для хранения строки никакой памяти не выделяется. Если строка не является пустой, то данная переменная указывает на динамически размещаемый блок памяти, содержащий значение строки, на 32-битовое значение длины строки и на 32 битовое значение счетчика ссылок на строку.
Несколько идентификаторов строк могут ссылаться на одну строку. При этом им не будет выделяться дополнительная память, а только будет выполняться увеличение счетчика ссылок.
Объявление переменных выполняется в секции, начинающейся с ключевого слова var. Ключевое слово const предназначено для объявления констант.
Константами могут быть простые значения или значения типа записи, массива, функции и указателя.
При объявлении константного указателя его сразу необходимо инициализировать.
Инициализация константного указателя может быть выполнена тремя способами:
Например:
const PI: ^Integer = @i1;
{ i1 - переменная типа Integer}
const StrNew: PChar = 'NewConst';
const PFunc: Pointer = @MyFunc;
Типы данных языка Java
Java - это язык со строгой типизацией. Это означает, что типы данных должны быть определены уже на этапе компиляции.
Все типы данных в Java можно подразделить на две группы:
Язык Java позволяет использовать следующие простые типы:
целые типы:
типы значений с плавающей точкой:
Например:
// Объявление переменных
boolean b1=true;
float fN1=74.3F;
float fN2=(float)(fN1+2);
double dN1=14573.74;
double dN2= 81.2E-2;
Значение одного целого типа может быть приведено к значению другого целого типа.
Приведение целых типов к логическому и обратно выполнять нельзя.
Язык Java предусматривает для целочисленных значений следующие операторы:
Если оба операнда имеют целочисленный тип, то операция рассматривается как целочисленная. Если один из операндов имеет тип long, то операция выполняется с использованием 64-битового представления: при этом любой другой операнд будет расширен до типа long и результат будет также иметь тип long. В противном случае операции выполняются, используя 32-битовое представление (любой операнд, не являющийся int, первоначально расширяется до типа int) и результат будет иметь тип int.
Логические значения представляются одним битом и обозначаются константами true и false
В языке Java нельзя прямо выполнить приведение типа int к типу boolean, но можно конвертировать значение int, используя следующий синтаксис языка: int x != 0, где любое не нулевое значение x даст в результате true, а нулевое значение даст false. Для преобразования значения типа boolean в целое следует выполнить условный оператор: bool x ? 1:0.
Для логических значений в языке Java предусмотрены следующие операторы:
Типы данных языка C#
В языке C# нет базовых типов - все типы реализуются как классы библиотеки NET Framework. Однако язык C# имеет набор встроенных типов, которые рассматриваются как псевдонимы типов в пространстве имен System. Например, тип string - это псевдоним типа System.String, а тип int - псевдоним типа System.Int32.
C# поддерживает следующие встроенные типы:
Все встроенные типы подразделены на группы:
Иерархия классов NET Framework имеет один общий корень - класс System.Object.
Все типы разделяются на две категории:
При создании переменной размерного типа под нее в стеке выделяется определенный объем памяти, соответствующий типу этой переменной. При передаче такой переменной в качестве параметра выполняется передача значения, а не ссылки на него. Значение размерного типа не может быть равным null. К размерным типам относятся целочисленные и вещественные типы, структуры, перечислимые типы.
При создании переменной ссылочного типа память под созданный объект выделяется в куче. Ссылка всегда указывает на объект заданного типа.
В языке C# все массивы являются объектами. Базовым классом массива является класс Array пространства имен Systems.
Язык C# позволяет создавать следующие массивы:
Массивы относятся к ссылочным типам.
Одномерный массив можно создать одним из следующих способов:
Отметим, что нельзя выполнять инициализацию массива в форме myArray5 = {1, 2}; для предварительно объявленного или уже созданного массива.
При создании многомерных массивов их размерность определяется числом запятых плюс один, указанных в квадратных скобках после типа массива. Формы создания многомерного массива аналогичны формам создания одномерного массива.
Например:
int[,] iArr1 = new int[8,2];
Невыровненный массив реализуется как массив массивов.
Например, массив из трех элементов, каждый из которых содержит двумерный массив, может быть описан следующим образом:
int[][,] iJaggedArr1 = new int [3][,]
{ new int[,] { {1,1}, {8,8} },
// первый элемент массива
new int[,] { {5,5}, {6,6}, {7,7} },
// второй элемент массива
new int[,] { {0,0}, {0,0}, {0,0} }
// третий элемент массива
};
Операторы new должны использоваться для создания каждого массива: первое вхождение оператора new создает одномерный массив, каждый из трех элементов которого также является массивом, а три следующих вхождения оператора new создают элементы как двумерные массивы.
В обычных массивах индексы элементов представляют собой подряд идущие целочисленные значения. Библиотека NET Framework предоставляет класс Collections.Hashtable, позволяющий создавать хэшированные массивы.
Например:
Collections.Hashtable hArr = new
Collections.Hashtable();
hArr["i"] = 175;
// Значение индекса указывается
// типом string
Представление целочисленных и вещественных значений в памяти компьютера в большинстве случаев реализуется аппаратным способом с учетом возможностей конкретного процессора. Также аппаратно реализуется примитивный набор операций над этими значениями. Применение операций, реализуемых аппаратно, значительно более эффективно, чем использование программно реализуемых операций. Поэтому компиляторы по возможности формируют код, в котором применяется аппаратная реализация примитивных операций (таких, как сложение, вычитание, умножение и деление).
Целочисленное значение типа integer, записанное как "signed 32-bit", может иметь в памяти компьютера следующее представление:
Целочисленное значение типа shortint, записанное как " signed 8-bit ", может иметь в памяти компьютера следующее представление:
Максимально допустимое значение, которое можно записать в 7 бит - это восьмеричное число 177, которое в десятичном исчислении равно 127 (1778=1*82+7*81+7*80=12710).
Таким образом, диапазон допустимых значений для каждого целочисленного типа данных определяется как стандартом языка, так и возможностями аппаратуры.
В некоторых языках программирования представление целочисленного значения включает еще и хранение дескриптора этого значения. При этом дескриптор может храниться как в одной ячейке со значением, так и в различных ячейках. В первом случае наличие дескриптора значительно уменьшает диапазон допустимых значений, а также, как правило, замедляет процесс выполнения арифметических операций (операции над частью ячейки памяти не поддерживаются аппаратно).
При хранении дескриптора и значения в разных ячейках (этот способ представления используется для языка LISP) одновременно с дескриптором хранится и указатель физического расположения значения.
Вещественные типы аппаратно могут иметь два представления: вещественные числа с фиксированной точкой и вещественные числа с плавающей точкой. Как правило, по умолчанию компиляторы преобразуют вещественные значения в экспоненциальный формат (формат с плавающей точкой), если синтаксис языка явно не указывает применение формата с фиксированной точкой.
Вещественное значение с плавающей точкой может иметь в памяти компьютера следующее представление:
Для представления вещественных чисел с плавающей точкой и вещественных чисел двойной точности с плавающей точкой стандартом IEEE 754 определены 32- и 64-битовые представления соответственно.
В разряды мантиссы записываются значащие цифры, а в разряды экспоненты заносится показатель степени. Положительные значения содержат в знаковом бите числа - 0, а отрицательные значения - 1.
При обозначении чисел с плавающей точкой приняты следующие соглашения: знаковый разряд обозначается буквой s, экспонента - e, а мантисса - m.
В языке Java значения с плавающей точкой могут объявляться следующими базовыми типами:
Полной ненулевой формой значения типа float является форма s·m·2e, где s это +1 или -1 (знаковый бит числа), m является положительным значением, меньшим, чем 224 (мантисса), и e является целым в пределах от -149 до 104 включительно (экспонента).
Полной ненулевой формой значения типа double является форма s·m·2e, где s это +1 или -1, m является положительным значением, меньшим, чем 253, и e является целым в пределах от -1045 до 1000 включительно.
Положительным нулевым значением и отрицательным нулевым значением являются 0.0 и -0.0 (0.0 == -0.0 дает в результате true), но некоторые операторы различают эти "эквивалентные" значения, например, 1.0/0.0 равно положительной бесконечности, а 1.01/-0.0 - отрицательной бесконечности.
В языке Java приняты следующие правила приведения вещественных типов:
Если оба операнда имеют тип float, или один имеет тип float, а другой - целый тип, то результат будет иметь тип float.
Если же хотя бы один из операндов имеет тип double (устанавливаемый по умолчанию), то другой операнд также приводится к типу double и результат будет иметь тип double.
Операции со значениями с плавающей точкой не выдают исключений.
При вычислениях значений с плавающей точкой следует учитывать правила округления. Так например, для значений с плавающей точкой выражение1.0*10 не равно значению 10. Это иллюстрирует следующий пример на языке Java:
public class MyFloatSumma
{ public static void main(String[] args)
{
float f1 = (float) 1.0;
// Число с плавающей точкой
float fSum = 0;
// Переменная для записи результата
final static float myDeltaFloat =
(float) 0.00001;
// Дельта для "усечения"
// мусора мантиссы
// Способ вычисления - простое
// суммирование и сравнение
for (byte i=0; i<10; i++)
fSum = fSum + (float) 0.1;
// Цикл от 0 до 10
if (f1 == fSum)
// Сравнение (float) 1.0 и
// полученной суммы
System.out.println("Числа равны");
else
System.out.println("Числа различны");
// Правильный способ вычисления -
// с "усечением" мусора мантиссы
fSum = 0;
for (byte i=0; i<10; i++)
fSum = fSum + (float) 0.1;
if (Math.abs(fSum - f2) < myDeltaFloat)
System.out. println("Числа одинаковы");
else
System.out. println("Числа различны");
}
}