#include <iostream>
#include <iomanip>
#include <cstddef>
#include <cstdint>
#include <cstring>
using namespace std;

struct Student {
    char name[17];
    uint16_t year;
    float average_score;
    uint8_t gender : 1;
    uint8_t courses : 7;
    Student* head_student;
};

void print_hex(const void* data, size_t size) {
    const uint8_t* bytes = reinterpret_cast<const uint8_t*>(data);
    for (size_t i = 0; i < size; i++) {
        cout << hex << uppercase << setw(2) << setfill('0')
             << static_cast<int>(bytes[i]) << " ";
    }
    cout << dec;
}

void print_binary(const void* data, size_t size) {
    const uint8_t* bytes = reinterpret_cast<const uint8_t*>(data);
    for (size_t i = 0; i < size; i++) {
        for (int j = 7; j >= 0; j--) {
            cout << ((bytes[i] >> j) & 1);
        }
        cout << " ";
    }
}

int main() {
    Student students[3];

    strcpy(students[0].name, "Ivanov Ivan");
    students[0].year = 2023;
    students[0].average_score = 4.5f;
    students[0].gender = 1;
    students[0].courses = 2;
    students[0].head_student = nullptr;

    strcpy(students[1].name, "Petrova Anna");
    students[1].year = 2023;
    students[1].average_score = 4.8f;
    students[1].gender = 0;
    students[1].courses = 2;
    students[1].head_student = &students[0];

    strcpy(students[2].name, "Sidorov Petr");
    students[2].year = 2023;
    students[2].average_score = 4.2f;
    students[2].gender = 1;
    students[2].courses = 2;
    students[2].head_student = &students[0];

    cout << "1. Информация о массиве:" << endl;
    cout << "Адрес массива: " << &students << endl;
    cout << "Размер массива: " << sizeof(students) << " байт" << endl << endl;

    cout << "2. Информация об элементах массива:" << endl;
    for (int i = 0; i < 3; i++) {
        cout << "Студент " << i << ":" << endl;
        cout << "Адрес: " << &students[i] << endl;
        cout << "Размер: " << sizeof(Student) << " байт" << endl << endl;
    }

    cout << "3. Детальная информация о полях второго студента:" << endl;

    cout << "name:" << endl;
    cout << "  Адрес: " << static_cast<void*>(students[1].name) << endl;
    cout << "  Смещение: " << offsetof(Student, name) << endl;
    cout << "  Размер: " << sizeof(students[1].name) << " байт" << endl;
    cout << "  Hex: ";
    print_hex(students[1].name, sizeof(students[1].name));
    cout << endl << "  Bin: ";
    print_binary(students[1].name, sizeof(students[1].name));
    cout << endl << endl;

    cout << "year:" << endl;
    cout << "  Адрес: " << &students[1].year << endl;
    cout << "  Смещение: " << offsetof(Student, year) << endl;
    cout << "  Размер: " << sizeof(students[1].year) << " байт" << endl;
    cout << "  Hex: ";
    print_hex(&students[1].year, sizeof(students[1].year));
    cout << endl << "  Bin: ";
    print_binary(&students[1].year, sizeof(students[1].year));
    cout << endl << endl;

    cout << "average_score:" << endl;
    cout << "  Адрес: " << &students[1].average_score << endl;
    cout << "  Смещение: " << offsetof(Student, average_score) << endl;
    cout << "  Размер: " << sizeof(students[1].average_score) << " байт" << endl;
    cout << "  Hex: ";
    print_hex(&students[1].average_score, sizeof(students[1].average_score));
    cout << endl << "  Bin: ";
    print_binary(&students[1].average_score, sizeof(students[1].average_score));
    cout << endl << endl;

    cout << "head_student:" << endl;
    cout << "  Адрес: " << &students[1].head_student << endl;
    cout << "  Смещение: " << offsetof(Student, head_student) << endl;
    cout << "  Размер: " << sizeof(students[1].head_student) << " байт" << endl;
    cout << "  Hex: ";
    print_hex(&students[1].head_student, sizeof(students[1].head_student));
    cout << endl << "  Bin: ";
    print_binary(&students[1].head_student, sizeof(students[1].head_student));
    cout << endl << endl;

    cout << "4. Шестнадцатеричное представление структур:" << endl;
    for (int i = 0; i < 3; i++) {
        cout << "Студент " << i << " (староста: " << (i == 0 ? "да" : "нет") << "):" << endl;
        cout << "  Все поля: ";
        print_hex(&students[i], sizeof(Student));
        cout << endl;
        cout << "  name: ";
        print_hex(&students[i].name, sizeof(students[i].name));
        cout << endl;
        cout << "  year: ";
        print_hex(&students[i].year, sizeof(students[i].year));
        cout << endl;
        cout << "  average_score: ";
        print_hex(&students[i].average_score, sizeof(students[i].average_score));
        cout << endl;

        // Получаем значение байта, содержащего битовые поля
        uint8_t bit_fields = (students[i].gender << 7) | students[i].courses;
        cout << "  gender и courses (как байт): ";
        print_hex(&bit_fields, sizeof(bit_fields));
        cout << endl;

        cout << "  head_student: ";
        print_hex(&students[i].head_student, sizeof(students[i].head_student));
        cout << endl << endl;
    }

    return 0;
}