Исследование представления и размещения данных в памяти

main
SpelnikovNS 4 месяцев назад
Родитель 0bf7a1136f
Сommit 3b7c8eda07

182
3.cpp

@ -0,0 +1,182 @@
#include <iostream>
#include <iomanip>
#include <cassert>
#include <cstdint>
#include <cstddef> // для offsetof
#include <locale> // для 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<const uint8_t*>(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. Примерные данные для тестирования
Student students[3] = {
{"Алексей Петров", 2023, 4.0f, 1, 5, nullptr}, // Мужчина, 5 курсов
{"Мария Иванова", 2022, 3.8f, 0, 6, nullptr}, // Женщина, 6 курсов
{"Дмитрий Смирнов", 2021, 4.5f, 1, 7, nullptr} // Мужчина, 7 курсов
};
// 2. Печать информации о массиве студентов
cout << "\n1) Адрес и размер массива студентов:" << endl;
cout << "Адрес массива: " << static_cast<void*>(students) << endl;
cout << "Размер массива: " << sizeof(students) << " байт" << endl;
// 3. Печать информации о каждом студенте
for (int i = 0; i < 3; i++) {
cout << "\n2) Адрес и размеры элементов массива Student[" << i << "]:" << endl;
cout << "Адрес: " << static_cast<void*>(&students[i]) << endl;
cout << "Размер: " << sizeof(students[i]) << " байт" << endl;
}
// 4. Печать информации о полях первого студента (например, для "Мария Иванова")
cout << "\n3) Сведения о полях первого студента (Мария Иванова):" << endl;
Student& maria = students[1]; // Берем второго студента для примера
// Печать имени
cout << "Имя:" << endl;
cout << "Адрес: " << static_cast<void*>(maria.name) << endl;
cout << "Смещение: " << offsetof(Student, name) << " байт" << endl;
cout << "Размер: " << sizeof(maria.name) << " байт" << endl;
cout << "Шестнадцатеричное представление имени: ";
for (size_t i = 0; i < sizeof(maria.name); i++) {
cout << hex << (static_cast<int>(maria.name[i]) & 0xFF) << " ";
}
cout << "\nДвоичное представление имени: ";
for (size_t i = 0; i < sizeof(maria.name); i++) {
for (int bit = 7; bit >= 0; --bit) {
cout << ((maria.name[i] & (1 << bit)) ? '1' : '0');
}
cout << " ";
}
cout << "\n\n";
// Печать года поступления
cout << "Год поступления:" << endl;
cout << "Адрес: " << &maria.admissionYear << endl;
cout << "Смещение: " << offsetof(Student, admissionYear) << " байт" << endl;
cout << "Размер: " << sizeof(maria.admissionYear) << " байт" << endl;
cout << "Шестнадцатеричное представление: " << hex << maria.admissionYear << endl;
cout << "Двоичное представление: ";
for (int bit = 15; bit >= 0; --bit) {
cout << ((maria.admissionYear & (1 << bit)) ? '1' : '0');
}
cout << "\n\n";
// Печать среднего балла
cout << "Средний балл:" << endl;
cout << "Адрес: " << &maria.averageGrade << endl;
cout << "Смещение: " << offsetof(Student, averageGrade) << " байт" << endl;
cout << "Размер: " << sizeof(maria.averageGrade) << " байт" << endl;
cout << "Шестнадцатеричное представление: " << hex << *reinterpret_cast<uint32_t*>(&maria.averageGrade) << endl; // Преобразуем float к int для вывода
cout << "Двоичное представление: ";
uint32_t averageGradeBits = *reinterpret_cast<uint32_t*>(&maria.averageGrade);
for (int bit = 31; bit >= 0; --bit) {
cout << ((averageGradeBits & (1 << bit)) ? '1' : '0');
}
cout << "\n\n";
// Печать пола
cout << "Пол:" << endl;
cout << "Значение: " << static_cast<int>(maria.gender) << endl; // Просто печать значения
cout << "Размер (один бит): 1 бит" << endl;
cout << "\n\n";
// Печать количества курсов
cout << "Количество курсов:" << endl;
cout << "Адрес: " << &maria.coursesCount << endl;
cout << "Смещение: " << offsetof(Student, coursesCount) << " байт" << endl;
cout << "Размер: " << sizeof(maria.coursesCount) << " байт" << endl;
cout << "Шестнадцатеричное представление: " << hex << maria.coursesCount << endl;
cout << "Двоичное представление: ";
for (int bit = 31; bit >= 0; --bit) {
cout << ((maria.coursesCount & (1 << bit)) ? '1' : '0');
}
cout << "\n\n";
// 5. Печать всех студентов в шестнадцатеричном виде
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<int>(reinterpret_cast<uint8_t*>(&students[i])[j]) & 0xFF) << " ";
}
cout << endl;
}
return 0;
}
Загрузка…
Отмена
Сохранить