Собственно говоря столкнулся с одной вещью. Требовалось реализовать быструю работу с битами для большого массива. т.е. зная начало памяти и индекс бита, уметь проверять его установленность, сбрасывать и устанавливать. Очень удобно использовать такие массивы когда требуется хранить большое кол-во значений true / false. т.е. по сравнению с обычными байтовыми массивами - используется в 8 раз меньше памяти. И вот написал 3 макроса, может кому нибудь будут полезны: Code: #define SET_BIT(mem, index)(((DWORD*)mem)[index >> 5] |= (1 << (index & 0x1F))) #define UNSET_BIT(mem, index)(((DWORD*)mem)[index >> 5] ^= (1 << (index & 0x1F))) #define ISSET_BIT(mem, index)(((DWORD*)mem)[index >> 5] & (1 << (index & 0x1F))) Сделал в таком виде для того, чтобы код функций всегда был подставляемым, а не вызывался каждый раз. К тому же VS(да и другие компиляторы) довольно хорошо умеет оптимизировать функции в таком виде, нежели обычные (порой даже __inline и __declspec(naked) такого результата не дадут). Использование функции: Первый параметр - адрес памяти Второй параметр - индекс бита от начала памяти. Функция ISSET_BIT возвращает значение 0 если бит не установлен и не нулевое значение если установлен. Таким образом можно адресовать массив до 4 миллиардов битов который будет занимать в памяти 512 мегобайт. Память желательно чтобы была выравненная на 4 байта. Так быстрее работать будет.
2slesh Code: #define SET_BIT(mem, index)(((DWORD*)(mem))[(index) >> 5] |= (1 << ((index) & 0x1F))) #define UNSET_BIT(mem, index)(((DWORD*)(mem))[(index) >> 5] ^= (1 << ((index) & 0x1F))) #define ISSET_BIT(mem, index)(((DWORD*)(mem))[(index) >> 5] & (1 << ((index) & 0x1F))) в макросе можно ожидать подлости от такого i++ но не от такого expr ^ expr или expr | expr или expr + expr без скобочек в каждом случае даст неправильный результат
2 greki_hoy Ну как бы если юзаешь, то должен знать это. Да и нагромождать код зачем. Также запросто можно выйти за пределы массива. но это уже другая история. Но для обычных операций пойдет.
2 slesh для лучшей защиты также можно рассматривать индекс как беззнаковое при сдвиге Code: #define SET_BIT(mem, index) \ (((DWORD*)(mem))[(DWORD)(index) >> 5] |= (1 << ((index) & 0x1F))) #define UNSET_BIT(mem, index) \ (((DWORD*)(mem))[(DWORD)(index) >> 5] ^= (1 << ((index) & 0x1F))) #define ISSET_BIT(mem, index) \ (((DWORD*)(mem))[(DWORD)(index) >> 5] & (1 << ((index) & 0x1F)))