From 348059fc45b9321f407f4834a61dae97f3a9769d Mon Sep 17 00:00:00 2001 From: PvlukhinaYA Date: Wed, 25 Dec 2024 23:03:12 +0300 Subject: [PATCH] =?UTF-8?q?=D0=97=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5=5F3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lab04_3.cpp | 223 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100644 lab04_3.cpp diff --git a/lab04_3.cpp b/lab04_3.cpp new file mode 100644 index 0000000..0d2913d --- /dev/null +++ b/lab04_3.cpp @@ -0,0 +1,223 @@ +#include +#include +#include +#include +#include // для offsetof +#include // для setlocale + +using namespace std; + + +// Функция для преобразования значения от 0 до 15 в шестнадцатеричную цифру +char nibble_to_hex(uint8_t i) +{ + assert(0x0 <= i && i <= 0xf); + const char digits[] = "0123456789abcdef"; + return digits[i]; +} + +// Извлечение младшего nibble +uint8_t get_lower_nibble(uint8_t byte) +{ + return byte & 0x0F; +} + +// Извлечение старшего nibble +uint8_t get_upper_nibble(uint8_t byte) +{ + return byte >> 4; +} + +// Печать байта в шестнадцатеричном виде +void print_in_hex(uint8_t byte) +{ + cout << nibble_to_hex(get_upper_nibble(byte)) + << nibble_to_hex(get_lower_nibble(byte)); +} + +// Преобразование void* в uint8_t* +const uint8_t* as_bytes(const void* data) +{ + return reinterpret_cast(data); +} + +// Печать блока данных в шестнадцатеричном виде +void print_in_hex(const void* data, size_t size) +{ + const uint8_t* bytes = as_bytes(data); + for (size_t i = 0; i < size; i++) + { + print_in_hex(bytes[i]); + if ((i + 1) % 16 == 0) + { + cout << '\n'; + } + else + { + cout << ' '; + } + } +} + +// Печать байта в двоичном виде +void print_in_binary(uint8_t byte) +{ + for (int bit = 7; bit >= 0; --bit) + { + cout << ((byte & (1 << bit)) ? '1' : '0'); + } +} + +// Печать блока данных в двоичном виде +void print_in_binary(const void* data, size_t size) +{ + const uint8_t* bytes = as_bytes(data); + for (size_t i = 0; i < size; i++) + { + print_in_binary(bytes[i]); + if ((i + 1) % 4 == 0) + { + cout << '\n'; + } + else + { + cout << ' '; + } + } +} + +// Определение структуры Student +struct Student +{ + char name[17]; // Имя (массив из 17 символов) + uint16_t admissionYear; // Год поступления (2 байта) + float averageGrade; // Средний балл (с плавающей запятой) + uint8_t gender : 1; // Пол (0 - женский, 1 - мужской) + uint32_t coursesCount; // Количество пройденных курсов + Student* groupLeader; // Указатель на старосту группы +}; + +int main() +{ + // Устанавливаем локаль для отображения русских букв + setlocale(LC_ALL, "Russian"); + + // 1. Самопроверка nibble_to_hex() + for (uint8_t i = 0; i < 16; i++) + { + assert(nibble_to_hex(i) == (i < 10 ? '0' + i : 'a' + (i - 10))); + } + + // 1. Примерные данные для тестирования + uint8_t byte = 0xab; + + // Печать в шестнадцатеричном виде + cout << "Hex: "; + print_in_hex(byte); + cout << '\n'; + + // Печать в двоичном виде + cout << "Binary: "; + print_in_binary(byte); + cout << '\n'; + + // 2. Создаем и заполняем массив из трех структур Student + Student students[3] = + { + {"Alice Johnson", 2022, 3.5, 0, 4, nullptr}, // Женщина, 4 курса + {"John Smith", 2021, 3.8, 1, 5, nullptr}, // Мужчина, 5 курсов + {"", 0, 0.0, 0, 0, nullptr} // Староста (нулевой) + }; + + // 2.1 Печать информации о массиве + cout << "\n1) Адрес и размер массива: " << endl; + cout << "Адрес массива: " << static_cast(students) << endl; + cout << "Размер массива: " << sizeof(students) << " байт" << endl; + + for (int i = 0; i < 3; i++) + { + cout << "2) Адреса и размеры элементов массива (Student[" << i << "]): " << endl; + cout << "Адрес: " << static_cast(&students[i]) << endl; + cout << "Размер: " << sizeof(students[i]) << " байт" << endl; + } + + cout << "\n3) Сведения о полях одного элемента (Student[0]): " << endl; + Student& alice = students[0]; // Первый студент для примера + + cout << "Имя:" << endl; + cout << "Адрес: " << static_cast(alice.name) << endl; + cout << "Смещение: " << offsetof(Student, name) << " байт" << endl; + cout << "Размер: " << sizeof(alice.name) << " байт" << endl; + cout << "Шестнадцатеричное: "; + for (size_t i = 0; i < sizeof(alice.name); i++) { + cout << hex << (static_cast(alice.name[i]) & 0xFF) << " "; + } + cout << "\nДвоичное: "; + for (size_t i = 0; i < sizeof(alice.name); i++) + { + for (int bit = 7; bit >= 0; --bit) + { + cout << ((alice.name[i] & (1 << bit)) ? '1' : '0'); + } + cout << " "; + } + cout << "\n\n"; + + // Печать информации для остальных полей + cout << "Год поступления:" << endl; + cout << "Адрес: " << &alice.admissionYear << endl; + cout << "Смещение: " << offsetof(Student, admissionYear) << " байт" << endl; + cout << "Размер: " << sizeof(alice.admissionYear) << " байт" << endl; + cout << "Шестнадцатеричное: " << hex << alice.admissionYear << endl; + cout << "Двоичное: "; + for (int bit = 15; bit >= 0; --bit) + { + cout << ((alice.admissionYear & (1 << bit)) ? '1' : '0'); + } + cout << "\n\n"; + + cout << "Средний балл:" << endl; + cout << "Адрес: " << &alice.averageGrade << endl; + cout << "Смещение: " << offsetof(Student, averageGrade) << " байт" << endl; + cout << "Размер: " << sizeof(alice.averageGrade) << " байт" << endl; + cout << "Шестнадцатеричное: " << hex << *reinterpret_cast(&alice.averageGrade) << endl; // Преобразуем float к int для вывода + cout << "Двоичное: "; + uint32_t averageGradeBits = *reinterpret_cast(&alice.averageGrade); + for (int bit = 31; bit >= 0; --bit) + { + cout << ((averageGradeBits & (1 << bit)) ? '1' : '0'); + } + cout << "\n\n"; + + // Печать данных для поля "Пол" + cout << "Пол:" << endl; + cout << "Значение: " << static_cast(alice.gender) << endl; // Просто печать значения + cout << "Размер (один бит): 1 бит" << endl; // Размер битового поля фиксированный + cout << "\n\n"; + + cout << "Количество пройденных курсов:" << endl; + cout << "Адрес: " << &alice.coursesCount << endl; + cout << "Смещение: " << offsetof(Student, coursesCount) << " байт" << endl; + cout << "Размер: " << sizeof(alice.coursesCount) << " байт" << endl; + cout << "Шестнадцатеричное: " << hex << alice.coursesCount << endl; + cout << "Двоичное: "; + for (int bit = 31; bit >= 0; --bit) + { + cout << ((alice.coursesCount & (1 << bit)) ? '1' : '0'); + } + cout << "\n\n"; + + // 4. Печать всех элементов массива в шестнадцатеричном виде с их назначением + cout << "4) Все элементы массива в шестнадцатеричном виде:" << endl; + for (int i = 0; i < 3; i++) + { + cout << "Student[" << i << "] = "; + for (size_t j = 0; j < sizeof(students[i]); j++) + { + cout << hex << setw(2) << setfill('0') << (static_cast(reinterpret_cast(&students[i])[j]) & 0xFF) << " "; + } + cout << endl; + } + + return 0; +} \ No newline at end of file