
Структуры и типы данных.pptx
- Количество слайдов: 63
Структуры и типы данных
Простые структуры • Данные простых структур, являющиеся операндами машинных команд или операндами инструкций языков программирования, подразделяются на типы. • Числовые (целые, вещественные, булевы) • Нечисловые (символы, строки)
Байт Представление содержимого байта двумя шестнадцатеричными цифрами называется дампом байта 3
Число со знаком Двоичное целое (число со знаком) – положительное число – в нормальной позиционной системе счисления – отрицательное число – в дополнительном коде Как строится дополнительный код: – записывается абсолютное значение числа; – полученный код инвертируется; – добавляется 1 в младший разряд.
Примеры записи отрицательных чисел Число -1: абс. значение: инверсия: добавка 1: дамп: Число -128: абс. значение: инверсия: добавка 1: дамп: 0 0 0 1 1 1 0 1 1 1 1 FF 1 0 0 0 0 0 1 1 1 1 1 0 0 0 0 80 = 27 5
Числа со знаком • Двоичное число 1 0 0 0 0 как беззнаковое это число 128, а как целое (со знаком) это число -128. • Двоичное число 1111 по той же причине либо 255, либо -1.
Особенность арифметики целых чисел 127 + 1 = ? 0 1 1 1 127 = 28 – 1 + ______1 1 0 0 0 0 - это число – 128! Результат: 127 + 1 = – 128 7
Слово Цепочка байтов, равная по длине (по числу битов) регистру процессора. IBM PC: слово – 2 байта по четному адресу. Сейчас: слово – 4 байта по адресу, кратному 4. В регистре процессора байт с меньшим адресом расположен справа. Порядок следования байтов слова в памяти и в регистре процессора противоположный. Пример: слово памяти имеет дамп 8002. В слове хранится двухбайтовое число. Чему оно равно?
Двоичные целые числа Наименование типа Длина Левая граница числа, дамп значение байт Правая граница дамп значение byte 1 80 -128 7 F 127 unsigned byte 1 00 0 FF 255 short int 2 7 FFF -32768 8000 32767 unsigned short int 2 0000 0 FFFF 65536 int 4 8000 0000 -2 147 483 648 7 FFF FFFF 2 147 483 647 unsigned int 4 0000 0 FFFF 4 294 967 295
Концепция типа данных • Таким образом, тип данных определяет: а) множество значений, которые м. принимать данное; б) множество операций, определенных для данных; в) формат внутреннего хранения.
Числа с плавающей точкой • В процессорах Intel операции с числами действительного типа выполняет сопроцессор FPU (Floating Point Unit). • Все операции сопроцессор выполняет в 80 - или 96 -разрядных регистрах. • Традиционные для языков программирования 4 - и 8 -байтове форматы действительных чисел поддерживаются в регистрах основного процессора для интерфейса с памятью и программой
Размещение 4 -байтового вещественного числа в регистре процессора • Величина типа float занимает в памяти 4 байта, из которых 1 бит отводится для знака, 8 битов для порядка и 23 бита для мантиссы. • Для определения данных, представляющих число с плавающей точкой, используются ключевые слова float, double, long double.
Вещественные числа • Порядок хранится в виде двоичного положительного числа, которое получается при сложении величины порядка и числа 127 (11111112). • Пусть float x=5. 375; • в двоичной системе x 2=101. 011 или x 2=1. 01011 • 210+1111111 , • в нормализованной мантиссе первая цифра всегда 1, и эта единица отбрасывается, а порядок сдвигается на 127.
double • Величина типа double занимает 8 байт в памяти, формат которой аналогичен формату float. Биты памяти распределяются следующим образом: 1 бит – знак, 11 битов – порядок и 52 бита – мантисса. Порядок сдвигается на величину 1023. С учетом опущенного старшего бита мантиссы диапазон значений равен от 1. 7 E– 308 до 1. 7 E+308, а точность составляет 15 десятичных значащих цифр.
Диапазоны принимаемых значений • ± 1. 18 E-38 до ± 3. 39 E+38 4 б • ± 2. 23 E-308 до ± 1. 79 E+38 8 б • ± 3. 37 E-4932 до ± 1. 18 E+4932 10 б
Преобразование типов • В операторах и выражениях, вообще говоря, должны использоваться переменные и константы только одного типа. • Если все же вы смешаете типы в одном выражении, то компилятор с языка Си не считает программу неправильной, как это произошло бы при программировании на Паскале. Вместо этого компилятор использует набор правил для автоматического преобразования типов. Это очень удобно, но может оказаться и опасным, особенно если вы допустили смешение типов нечаянно.
Основные правила при преобразовании типов: 1. Если операция выполняется над данными двух различных типов, обе величины приводятся к "высшему" из двух типов. Этот процесс называется "повышением" типа. 2. Последовательность имен типов, упорядоченных от "высшего" к "низшему", выглядит так: double, float, long, int, short и char. Применение ключевого слова unsigned повышает ранг соответствующего типа данных со знаком. 3. В операторе присваивания конечный результат вычисления выражения в правой части приводится к типу переменной, которой должно быть присвоено это значение. Данный процесс может привести к "повышению" типа, как описано выше, или к "понижению”, при котором величина приводится к типу данных, имеющему более низкий приоритет
Понижение типа • «Повышение» типа обычно происходит гладко, в то время как «понижение» может привести к затруднениям. Причина этого проста: все число целиком может не поместиться в элементе данных низшего типа. Переменная типа char может принять целое значение 0, вместо 256.
• • • • /* Неявные преобразования */ main() { char ch; int i; float fl; fl = i = ch = 'А'; // «повышение типа» printf(" ch = %c, i = %d, fl = %2. 2 fn", ch, i, fl); ch = ch + 1; i = fl + 2*ch; // i – число целого типа fl = 2. 0*ch + i; // : перед умножением значение переменной ch('B') //преобразуется в число с плавающей точкой, перед сложением //I преобразуется в число с плавающей точкой printf(" ch = %c, i = %d, fl = %2. 2 fn", ch, i, fl); ch = 2. 0 e 30; printf(" Теперь ch = %с n" , ch); }
Операция приведения • Самое лучшее - это вообще избегать преобразования типов, особенно в порядке убывания ранга. Но иногда оказывается удобным применять такие преобразования при условии, что мы ясно представляем смысл выполняемых действий. Преобразования типов, которые мы обсуждали до сих пор, выполнялись автоматически. Существует возможность точно указывать тип данных, к которому необходимо привести величину. Этот способ называется приведением типов, и используется следующим образом: перед данной величиной в круглых скобках записывается имя требуемого типа. Скобки и имя типа вместе образуют операцию приведения. Например, (int)1. 6
Явное и неявное преобразование типов данных • x y Результат деления • делимое делитель частное x = 15 y = 2 • Int int 15/2=7 • int float 15/2=7. 5 • float int float 15/2=7. 5 Рассмотрим пример: int nice; nice = 1. 6+1. 7; nice = (int)1. 6+(int)1. 7
Упражнение Определите, чему будут равны следующие переменные: int a = 13 / 5; int b = 13 % 5; int c = 13. 0 / 5; double d = 13 / 5; double e = 13 % 5; double f = 13. 0 / 5; double g = 13 / 5 + 2 / 5; double h = 13. 0 / 5 + 2. 0 / 5; int i = 13. 0 / 5 + 2. 0 / 5;
Функции округления Функция round floor ceil trunc fabs Описание Округляет число по правилам арифметики, то есть round(1. 5) == 2, round(-1. 5) == -2 Округляет число вниз (“пол”), при этом floor(1. 5) == 1, floor(-1. 5) == -2 Округляет число вверх (“потолок”), при этом ceil(1. 5) == 2, ceil(-1. 5) == -1 Округление в сторону нуля (отбрасывание дробной части), при этом trunc(1. 5) == 1, trunc(1. 5) == -1 Модуль (абсолютная величина)
#include
Кодовые таблицы символов Заготовка кодовой таблицы: все числа байта в таблице 16× 16 Ц 0 1 2 3 4 5 6 и 7 ф р 8 а 9 A B C D E F 0 З о н а 1 2 3 4 5 6 7 8 9 A B 25
A S C I I (ASCII-7) Ц и ф р а 0 B C R S O SI G S R S US 1 EM ESC F F SUB LF VT BS CAN F ETB E BEL D ACK SYN C ENQ NAK HT A DC 4 9 EOT 8 DC 3 7 ETX 6 DC 2 5 STX 4 SOH DC 1 3 DLE 2 Nul 1 F S 2 ␣ ! " # $ % & ' ( ) * + , - . / 3 0 1 2 3 4 5 6 7 8 9 : ; < = > ? 4 @ A B C D E F G H I J K L M N O 5 6 P Q R S T U V W X Y Z [ ] ^ _ ` a b c d e f g h i j k l m n o 7 p q r s t u v w x y z { | } ~ Del 0 26
Управляющие символы ASCII Код 07 08 0 A 0 D 0 C 1 B Символ BEL (Bell - звонок) BS (Back Space - возврат) LF (Line Feed - перевод строки, ПС) CR (Carriage Return - возврат каретки, ВК) EOL (End Of Line) = CR + LF вводится с клавиатуры клавишей Enter (на некоторых клавиатурах - клавишей Return) FF (Form Feed – перевод формата, ПФ) На экране текстовых редакторов символ FF обычно обозначается знаком ♀. ESC (Escape – избавление) 27
Кодовые страницы (Code Page, CP) Кодовые страницы 16 -разрядных систем (DOS): установились стихийно – 457 – US для Западной Европы (символы основных национальных европейских алфавитов) – 866 – Россия (русский алфавит) Кодовые страницы 32 -разрядных систем: установлены ANSI – 1251 – Россия (русский алфавит) Unicode – 2 байта на символ – первые 128 символов – ASCII
Code page 866 ASCII Ц и ф р а 0 1 2 3 4 5 6 7 8 9 A B C D E F 8 А Б В Г Д Е Ж З И Й К Л М Н О П 9 Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я A а б в г д е ж з и й к л м н о п D E р с т у ф х ц ч ш щ ъ ы ь э ю я F Ё ё B C
Code page 1251 ANSI Ц 0 1 2 3 4 5 6 и 7 ф р 8 а 9 A B C D E F 8 9 A Ё B ё C А Б В Г Д Е Ж З И Й К Л М Н О П D E Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я а б в г д е ж з и й к л м н о п F р с т у ф х ц ч ш щ ъ ы ь э ю я
КОИ-8(Р) Ц 0 1 2 3 и ф р а 4 5 6 7 8 9 A B C D E F 8 9 A ё B Ё C ю а б ц д е ф г х и й к л м н о D E п я р с т у ж в ь ы з ш э щ ч ъ Ю А Б Ц Д Е Ф Г Х И Й К Л М Н О F П Я Р С Т У Ж В Ь Ы З Ш Э Щ Ч Ъ
Unicode • Юнико д — стандарт кодирования символов, позволяющий представить знаки практически всех письменных языков. • Коды в стандарте Юникод разделены на несколько областей. Область с кодами от U+0000 до U+007 F содержит символы набора ASCII с соответствующими кодами. Далее расположены области знаков различных письменностей, знаки пунктуации и технические символы.
Unicode • Для кириллицы в UNICODE отведен диапазон кодов от 0 x 0400 до 0 x 04 FF.
Unicode
Unicode • Ранние реализации хотели быть в состоянии хранить кодовые точки Unicode в формате с первым старшим байтом и первым младшим байтом (high-endian or low-endian), в зависимости от того, с каким форматом именно их процессор работал быстрее. Тогда возникло два способа хранить Unicode.
Unicode • Это привело к появлению причудливого соглашения о хранении кода u. FFFE в начале каждой строки Unicode. Эту сигнатуру называют меткой порядка байтов (byte order mark). Если вы поменяете местами ваши старший и младший байты, то в начале должно стоять u. FFFE. Данная сигнатура является зарезервированной в стандарте Unicode.
UTF-8 Интервал Unicode (шестнадцатиричный) Код UTF-8 (двоичный) 0 x 0000 – 0 x 007 F 0 xxxxxxx 0 x 0080 – 0 x 07 FF 110 xxxxxx 0 x 0800 – 0 x. FFFF 1110 xxxxxx
UTF-8 • Можно заметить, что если байт начинается с нулевого бита, то это однобайтовый символ ASCII. Если байт начинается с 11…, то это стартовый байт несколькобайтовой последовательности, кодирующей символ, число головных единичек которого равно количеству байт в последовательности. Если байт начинается с 10…, то это серийный «транспортный» байт из последовательности байтов, количество которых было определено стартовым байтом. Ну а биты Unicode символа упаковываются в «транспортные» биты стартового и серийных байтов, обозначенные в таблице как последовательность «xx. . x» .
Коды символов Unicode (HEX) 0000 — 0000007 F Размер в UTF-8 1 байт Представленные классы символов ASCII, в том числе латинский алфавит, простейшие знаки препинания и арабские цифры кириллица, расширенная латиница, арабский, армянский, греческий, еврейский и коптский алфавит; сирийское письмо, тана, нко; МФА; некоторые знаки препинания все другие современные формы письменности, в том числе грузинский алфавит, индийское, китайское, корейское и японское письмо; сложные знаки препинания; математические и другие специальные символы 00000080 — 000007 FF 2 байта 00000800 — 0000 FFFF 3 байта 00010000 — 001 FFFFF 4 байта музыкальные символы, редкие китайские иероглифы, вымершие формы письменности 00200000 — 03 FFFFFF 5 байт не используется в Unicode 04000000 — 7 FFFFFFF 6 байт не используется в Unicode
Статические агрегатные структуры • Агрегатные структуры состоят из конечного набора более простых структур. • В статических агрегатных структурах в течение всего времени выполнения программы ни перечень элементов структуры, ни связи между ними не изменяются
Массивы • Массивами называют агрегатные структуры, состоящие из однотипных элементов, расположенных в последовательных ячейках памяти • Элементы массива распознаются по индексу и по указателю: А[i] или *(A+i) • Размер массива – количество элементов • Размерность – количество измерений
Объявление массива
Динамические массивы
Последовательный поиск элемента в массиве
Бинарный поиск элемента в массиве
Сравнение двух методов
Матрицы • Матрица – это двумерный массив, т. е. массив с двумя измерениями • В памяти элементы матрицы хранятся следующим образом: сначала первая строка, потом вторая и т. д.
Обращение к элементам матрицы
Объявление матрицы
Преобразование матрицы в одномерный массив • for ( i = 0; i < M; i ++ ) • for ( j = 0; j < N; j ++ ) • B[i*N+j] = A[i][j]; • Сортировка строк матрицы? • Сортировка столбцов матрицы?
Работа с отдельными элементами
Работа с матрицей
Динамическое выделение памяти под матрицу
Динамическое выделение памяти под матрицу
Записи • Запись – это агрегатная структура, которая может включать в себя несколько полей – элементов разных типов (в том числе и другие структуры). • • • struct s. A {char a[2], s. A* this_struct; }; struct. A { struct. A *p. A; int i. A; } s. A; struct POINT { int x; // Объявление элементов x и y int y; } p_screen = { 50, 100 };
Объявление и инициализация
Обращение к полям записи
Поля записи каталога файловой системы FAT Байты Назначение 00 h… 07 h Имя файла Расширение имени Байт атрибутов Резерв Время и дата создания/модификации Начальный кластер Размер файла 08 h… 0 Ah 0 Bh 0 Ch… 15 h 16 h… 19 h 1 Ah… 1 Bh 1 Ch… 1 Fh
Таблицы Множество последовательных записей, имеющих одинаковую структуру. Как правило, одно из полей элементов таблицы отводится для хранения ключа. Типичные операции над таблицей: • включение новых данных; • поиск заданного элемента;
Массивы структур
Динамическое выделение памяти под массив структур
Сортировка таблицы по ключу