#include <iostream>
#include <iomanip>
#include <cstdint>
#include <cstring>
#include <bitset>

using namespace std;

// Структура Student, описывающая студента
struct Student {
    char name[17];            // Имя (массив из 17 символов, включая завершающий '\0')
    uint16_t year;            // Год поступления (беззнаковое целое, 2 байта)
    float average_score;      // Средний балл (с плавающей запятой)
    uint8_t gender : 1;       // Пол, представленный одним битом (0 — женский, 1 — мужской)
    uint8_t courses_passed;   // Количество пройденных курсов
    Student* group_leader;    // Указатель на структуру Student, описывающую старосту группы (для старосты — нулевой указатель)
};

int main() {
    // Объявление массива из трех структур Student
    Student students[3];

    // Заполнение массива данными о студентах
    strcpy(students[0].name, "Игорь");
    students[0].year = 2022;
    students[0].average_score = 3.38f;
    students[0].gender = 1;
    students[0].courses_passed = 1;
    students[0].group_leader = &students[2];

    strcpy(students[1].name, "Анна");
    students[1].year = 2021;
    students[1].average_score = 4.75f;
    students[1].gender = 0;
    students[1].courses_passed = 3;
    students[1].group_leader = &students[2];

    strcpy(students[2].name, "Мария");
    students[2].year = 2020;
    students[2].average_score = 4.92f;
    students[2].gender = 0;
    students[2].courses_passed = 5;
    students[2].group_leader = nullptr;

    // Печать адреса и размера массива
    cout << "Address of array: " << &students << ", size: " << sizeof(students) << " bytes\n\n";

    // Печать адресов и размеров всех элементов массива
    for (int i = 0; i < 3; i++) {
        cout << "Address of students[" << i << "]: " << &students[i]
             << ", size: " << sizeof(students[i]) << " bytes\n";
    }
    cout << '\n';

    // Печать информации о полях структуры для студента Игоря
    cout << "Information about fields of students[0] (Игорь):\n";
    cout << "Name: address: " << &students[0].name
         << ", offset: " << offsetof(Student, name)
         << ", size: " << sizeof(students[0].name) << " bytes\n";
    cout << "Year: address: " << &students[0].year
         << ", offset: " << offsetof(Student, year)
         << ", size: " << sizeof(students[0].year) << " bytes"
         << ", hex: " << hex << setw(4) << setfill('0') << students[0].year
         << ", bin: " << bitset<16>(students[0].year) << '\n';
    cout << "Average score: address: " << &students[0].average_score
         << ", offset: " << offsetof(Student, average_score)
         << ", size: " << sizeof(students[0].average_score) << " bytes\n";
    cout << "Courses passed: address: " << reinterpret_cast<void*>(&students[0].courses_passed)
         << ", offset: " << offsetof(Student, courses_passed)
         << ", size: " << sizeof(students[0].courses_passed) << " bytes"
         << ", hex: " << hex << static_cast<int>(students[0].courses_passed)
         << ", bin: " << bitset<8>(students[0].courses_passed) << '\n';
    cout << "Group leader: address: " << &students[0].group_leader
         << ", offset: " << offsetof(Student, group_leader)
         << ", size: " << sizeof(students[0].group_leader) << " bytes\n\n";

    // Печать всех элементов массива в шестнадцатеричном виде
    cout << "Array elements in hex:\n";
    for (int i = 0; i < 3; i++) {
        cout << "students[" << i << "]:\n";
        const uint8_t* bytes = reinterpret_cast<const uint8_t*>(&students[i]);
        for (size_t j = 0; j < sizeof(Student); j++) {
            cout << hex << setw(2) << setfill('0') << static_cast<int>(bytes[j]) << ' ';
            if ((j + 1) % 16 == 0) {
                cout << '\n';
            }
        }
        cout << '\n';
    }

    return 0;
}