У битовых полей есть неприятные ограничения, которые стоило бы озвучить. Использование битовых полей может сделать код платформ зависимым, т.к. стандартом не определен порядок, в котором биты хранятся в битовых полях. Так например, если у вас в программе будет реализована сериализация и десериализация структуры с битовыми полями (например для запись/чтение с диска), то такой код может оказаться нерабочим на платформе с другим порядком хранения байт. Операции с битовыми полями могут оказаться медленнее, чем операции с обычными переменными с применением битовых операций. К переменной битового поля нельзя применить операцию взятия адреса &.
Надеюсь я правильно понял, что Union хранит в одной месте памяти, какие либо типы данных. Допустим тот же char и int будут храниться в одном и том же месте, и вместо инициализации этих двух типов данных в лоб (в суме будут занимать 5 байт), можно проинициализировать эти же переменные в одном месте памяти но при этом будут занимать уже 4 байта (надеюсь я правильно понял и объяснил). Хотя в голову не приходит, где это можно применить на практике. Просто структуры будут более функциональные и можно обращаться к любой переменной. Буду рад если мне объяснят что да как, и где это может использоваться на практике)
На практике можно применить для изучения кодирования (представления) значений без использования отладчика. Правда получается платформозависимая вещь. Например, объединив поле float и массив из 4-х char можно изучать, как кодируется вещественный тип, если присвоить значение полю float, а выводить на печать код из char. Другой пример: union Vec3{ struct { float x; float y; float z; }; struct { float r; float g; float b; }; Здесь один и тот же тип Vec3 (3-х мерный вектор) содержит 3 вещественных поля и это могут быть координаты или цвет. Причем некоторые векторные операции имеют смысл и для координат и для цвета. Поля могут называться x,y,z или r,g,b. В данном случае объединение может использоваться для наглядности. Или вот реальный пример из winuser.h typedef struct tagINPUT { DWORD type; union { MOUSEINPUT mi; KEYBDINPUT ki; HARDWAREINPUT hi; }; }; Здесь type задает тип полученной информации, а объединение дает один из вариантов - данные от мыши, клавиатуры или иного устройства ввода. Если бы у нас было scruct вместо union, то мы понапрасну бы расходовали память на все 3 структуры, хотя использовалась только одна из них, потому что одно сообщение tagINPUT не может прийти от нескольких устройств сразу.
Про битовые поля тема раскрыта не полностью, а это мощное языковое средство, которого нет в других языках. Во-первых, битовый контейнер можно изменять: от char, до long long. Во-вторых, и это главное о чем не упомянули, это возможность создания знаковых целочисленных переменных любой длины, и компилятор будет с ними работать как с обыкновенным типом int, включая >>,% и все остальное… Может быть вы этого не знали? Так и многие этого не знают 😢 Не забудьте обязательно сделать видео про макроподстановки, тем более язык имеет некоторые модификации для этого. А в общем, вы прекрасно объясняете - без излишеств «в реальном» времени, за что вам обучающиеся должны выразить благодарность 😊
Кстати - не проверял, но может ряд компиляторов это поддерживает… Через typedef можно создать целочисленный контейнер и использовать его для задания битовых полей, выравненных по границе этого контейнера ? 😮 Компиляторы - они сейчас такие, например, многие имеют прагмы пакующие биты в байты без пропусков сплошным битовым потоком, что очень удобно.
Спасибо! Да, большинство компиляторов поддерживают, то что вы сказали в п. 1 и 2. Но, стандартом оговорен только тип unsigned int. Другие могут не поддерживаться.
во время урока все понятно но как только он заканчивается остается только шум в голове и ничего не ясно... нет применения никакого к урокам. уже почти курс закончен а понятия о программировании на языке Си так и нет. Что с этими знаниями делать дальше не ясно. На питоне я хоть игру и калькулятор написал сам уже в середине обучения... а здесь даже понятия нет что такое Си и с чем его едят. Даже драйвер не имею понятия как написать для устройства. с чего начитать то надо???
Хотел бы выразить благодарность за ваши уроки. Все интуитивно и понятно, спасибо!
У битовых полей есть неприятные ограничения, которые стоило бы озвучить. Использование битовых полей может сделать код платформ зависимым, т.к. стандартом не определен порядок, в котором биты хранятся в битовых полях. Так например, если у вас в программе будет реализована сериализация и десериализация структуры с битовыми полями (например для запись/чтение с диска), то такой код может оказаться нерабочим на платформе с другим порядком хранения байт. Операции с битовыми полями могут оказаться медленнее, чем операции с обычными переменными с применением битовых операций. К переменной битового поля нельзя применить операцию взятия адреса &.
Спасибо. Будем знать.
Хорошее обьяснение, спасибо!
Никогда так не использовал union. Он удобен для побайтового доступа к переменным.
Надеюсь я правильно понял, что Union хранит в одной месте памяти, какие либо типы данных. Допустим тот же char и int будут храниться в одном и том же месте, и вместо инициализации этих двух типов данных в лоб (в суме будут занимать 5 байт), можно проинициализировать эти же переменные в одном месте памяти но при этом будут занимать уже 4 байта (надеюсь я правильно понял и объяснил). Хотя в голову не приходит, где это можно применить на практике. Просто структуры будут более функциональные и можно обращаться к любой переменной. Буду рад если мне объяснят что да как, и где это может использоваться на практике)
На практике можно применить для изучения кодирования (представления) значений без использования отладчика. Правда получается платформозависимая вещь. Например, объединив поле float и массив из 4-х char можно изучать, как кодируется вещественный тип, если присвоить значение полю float, а выводить на печать код из char.
Другой пример:
union Vec3{
struct {
float x;
float y;
float z;
};
struct {
float r;
float g;
float b;
};
Здесь один и тот же тип Vec3 (3-х мерный вектор) содержит 3 вещественных поля и это могут быть координаты или цвет. Причем некоторые векторные операции имеют смысл и для координат и для цвета. Поля могут называться x,y,z или r,g,b. В данном случае объединение может использоваться для наглядности.
Или вот реальный пример из winuser.h
typedef struct tagINPUT {
DWORD type;
union {
MOUSEINPUT mi;
KEYBDINPUT ki;
HARDWAREINPUT hi;
};
};
Здесь type задает тип полученной информации, а объединение дает один из вариантов - данные от мыши, клавиатуры или иного устройства ввода. Если бы у нас было scruct вместо union, то мы понапрасну бы расходовали память на все 3 структуры, хотя использовалась только одна из них, потому что одно сообщение tagINPUT не может прийти от нескольких устройств сразу.
Спасибо
Про битовые поля тема раскрыта не полностью, а это мощное языковое средство, которого нет в других языках.
Во-первых, битовый контейнер можно изменять: от char, до long long.
Во-вторых, и это главное о чем не упомянули, это возможность создания знаковых целочисленных переменных любой длины, и компилятор будет с ними работать как с обыкновенным типом int, включая >>,% и все остальное…
Может быть вы этого не знали? Так и многие этого не знают 😢
Не забудьте обязательно сделать видео про макроподстановки, тем более язык имеет некоторые модификации для этого.
А в общем, вы прекрасно объясняете - без излишеств «в реальном» времени, за что вам обучающиеся должны выразить благодарность 😊
Кстати - не проверял, но может ряд компиляторов это поддерживает… Через typedef можно создать целочисленный контейнер и использовать его для задания битовых полей, выравненных по границе этого контейнера ? 😮 Компиляторы - они сейчас такие, например, многие имеют прагмы пакующие биты в байты без пропусков сплошным битовым потоком, что очень удобно.
Спасибо! Да, большинство компиляторов поддерживают, то что вы сказали в п. 1 и 2. Но, стандартом оговорен только тип unsigned int. Другие могут не поддерживаться.
union - это получается способ разные типы данных хранить под одним именем? Что-то типа списков в Питоне?
это способ разные типы данных хранить в одной и той же области памяти (начиная с одного адреса)
@Napalm13 Нет, это абсолютно не верно.
я не, совсем, понял: как получилось такое количество бит, не могли бы вы разъяснить, мне, по-подробнее.
Ну не скажите. Удобно получать доступ поьацтно, к любым переменным.
во время урока все понятно но как только он заканчивается остается только шум в голове и ничего не ясно... нет применения никакого к урокам. уже почти курс закончен а понятия о программировании на языке Си так и нет. Что с этими знаниями делать дальше не ясно. На питоне я хоть игру и калькулятор написал сам уже в середине обучения... а здесь даже понятия нет что такое Си и с чем его едят. Даже драйвер не имею понятия как написать для устройства. с чего начитать то надо???
Рекомендую вам поставить цель в программировании на C/C++ и добиваться её.