Я могу выделить определенное число битов в C?

Вы можете создать ServiceProvider следующим образом в app / Providers:

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class HelperServiceProvider extends ServiceProvider
{
    /**
    * Bootstrap the application services.
    *
    * @return void
    */
    public function boot()
    {
        //
    }

    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
        foreach (glob(app_path().'/Helpers/*.php') as $filename) {
            require_once($filename);
        }
    }
}

В файле config / app добавьте этот новый serviceProvier

App\Providers\HelperServiceProvider::class,

Затем создайте папку / Helpers в папке / app (./app/Helpers) и поместите ваш файл в эту папку. Теперь вы можете получить доступ ко всем функциям этой папки из любого места.

10
задан Jonathan Leffler 12 November 2008 в 20:57
поделиться

16 ответов

pStatus = malloc((<number of data points>/8) + 1);

Это действительно выделяет достаточно байтов для Ваших битов. Однако

pStatus[element]

Это получает доступ к element'th байту, не биту. Таким образом, когда элемент является больше чем одной восьмой общего количества битов, Вы получаете доступ от конца выделенного массива.

Я определил бы несколько функций помощника

int get_bit(int element)
{
    uint byte_index = element/8;
    uint bit_index = element % 8;
    uint bit_mask = ( 1 << bit_index);

    return ((pStatus[byte_index] & bit_mask) != 0);
}

void set_bit (int element)
{
    uint byte_index = element/8;
    uint bit_index = element % 8;
    uint bit_mask = ( 1 << bit_index);

    pStatus[byte_index] |= bit_mask);
}

void clear_bit (int element)
{
    uint byte_index = element/8;
    uint bit_index = element % 8;
    uint bit_mask = ( 1 << bit_index);

    pStatus[byte_index] &= ~bit_mask;
}

(проверка ошибок на диапазоне элемента не учтена для ясности. Вы могли сделать эти макросы, также),

29
ответ дан 3 December 2019 в 13:30
поделиться

Если Вы ограничены всего несколькими битами, Вы можете вместо eaanon01 решения также использовать c встроенное средство битового поля (существуют очень немногие случай, где Вы могли использовать их, но это будет одним),

Для этого бита, который наполняет стук, я могу recommendate: Herny Warrens "Хакер Delight"

-1
ответ дан 3 December 2019 в 13:30
поделиться

Булевская переменная никогда не является отдельным значением в C. Таким образом, структура могла бы быть в порядке для получения Вас движение.

Это верно, что Вы не инициализируете область мадам, таким образом, необходимо сделать это индивидуально.

Вот простой пример того, как Вы могли сделать это со структурами объединений и перечислениями

typedef unsigned char           BYTE;
typedef unsigned short          WORD;
typedef unsigned long int       DWORD;
typedef unsigned long long int  DDWORD;
enum STATUS
{
    status0 = 0x01,
    status1 = 0x02,
    status2 = 0x04,
    status3 = 0x08,
    status4 = 0x10,
    status5 = 0x20,
    status6 = 0x40,
    status7 = 0x80,
status_group = status0 + status1 +status4
};
#define GET_STATUS( S ) ( ((status.DDBuf&(DDWORD)S)==(DDWORD)S) ? 1 : 0  )
#define SET_STATUS( S ) (  (status.DDBuf|=  (DDWORD)S) )
#define CLR_STATUS( S ) (  (status.DDBuf&= ~(DDWORD)S) )
static union {
 BYTE   BBuf[8];
 WORD   WWBuf[4];
 DWORD  DWBuf[2];
 DDWORD DDBuf;
}status;

int main(void)
{
    // Reset status bits
    status.BBuf[0] = 0;
    printf( "%d \n", GET_STATUS( status0 ) );

    SET_STATUS( status0 );
    printf( "%d \n", GET_STATUS( status0 ) );

    CLR_STATUS(status0);
    printf( "%d \n", GET_STATUS( status0 ) );
    SET_STATUS( status_group );
    printf( "%d \n", GET_STATUS( status0 ) );
    system( "pause" );
    return 0;
}

Надеюсь, это поможет. Этот пример может обработать вплоть до 64 булевских переменных состояния и мог быть легок расширенный.

Этот пример основан на Символе = интервал на 8 битов = длинное целое на 16 битов = 32 биты и долгое длинное целое = 64 бита

Я теперь также добавил поддержку групп состояния.

-1
ответ дан 3 December 2019 в 13:30
поделиться

С чем было бы неправильным std::vector<bool>?

0
ответ дан 3 December 2019 в 13:30
поделиться

Вы код выделения является правильным, видят set_bit() и get_bit() функции, данные в этом ответе для доступа к булевской переменной.

-1
ответ дан 3 December 2019 в 13:30
поделиться

Если Вы не возражаете иметь необходимость записать обертки, Вы могли бы также использовать или bit_set или bit_vector от STL C++, кажется, что они (особенно последний) имеют точно, в чем Вы нуждаетесь, уже кодированный, протестированный и упакованный (и много дополнительных свойств).

Это - реальный позор, мы испытываем недостаток в прямом способе использовать код C++ в приложениях C (не, создавание обертки не просто мне, ни забаве, и означает больше работы в долгосрочной перспективе).

0
ответ дан 3 December 2019 в 13:30
поделиться
 pStatus = malloc((<number of data points>/8) + 1);

Штраф той части.

 pStatus[element]

вот то, где Вы испытываете затруднения. Вы - адресные байты, когда Вы хотите к адресным битам.

 pStatus[element / 8 ]  

получит Вас правильный байт в массиве.

0
ответ дан 3 December 2019 в 13:30
поделиться

Необходимо выделить c = malloc((N+7)/8) байты, и можно установить энное с

 c[n/8]=((c[n/8] & ~(0x80 >> (n%8))) | (0x80>>(n%8)));

ясный с

 c[n/8] &= ~(0x80 >> (n%8));

и тест с

 if(c[n/8] & (0x80 >> (n%8))) blah();
0
ответ дан 3 December 2019 в 13:30
поделиться

Сделайте себя более счастливыми и определите тип и функции для работы на тот тип. Тот путь, если Вы обнаруживаете, что разрядные доступы являются слишком медленными, можно изменить единицу памяти на булевскую переменную к байту/слову/длинному или принять редкие/динамичные структуры данных, если память является действительно проблемой (т.е., если наборы являются главным образом нулями, Вы могли бы просто сохранить список с координатами 1's.

Можно написать код, чтобы быть абсолютно неуязвимыми для изменений в реализации битовый вектора.

1
ответ дан 3 December 2019 в 13:30
поделиться

Маленькая точка: чтобы заставить достаточно памяти хранить биты N, (N/8) +, 1 байт неточен (могут быть слишком многие).

(N+7)/8 всегда является минимальным числом, все же.

5
ответ дан 3 December 2019 в 13:30
поделиться

pStatus [элемент] даст Вам весь байт в том адресе.

Для установки конкретного элемента, Вы сделали бы что-то как:

pStatus[element >> 3] |= 1 << (element & 7);

Сбрасывать элемент:

pStatus[element >> 3] &= ~1 << (element & 7);

и протестировать элемент:

if (pStatus[element >> 3] & (1 << (element & 7)) != 0)

начальное выделение должно быть

pstatus = malloc((<number of data points> + 7) / 8)

то, что Вы имели, будет работать, но иногда тратит впустую байт

2
ответ дан 3 December 2019 в 13:30
поделиться

Я не могу не заметить, что все ответы в C здесь, кажется, предполагают, что байт составляет 8 битов. Это не обязательно верно в C (хотя это, конечно, будет верно на самых основных аппаратных средствах), так создание этого предположения в коде является довольно невоспитанностью.

Надлежащий способ написать нейтральный в отношении архитектуры код к

#include <limits.h>

и затем используйте CHAR_BIT макрос везде, где Вам нужно "число битов в a char".

2
ответ дан 3 December 2019 в 13:30
поделиться

... думая, что это даст мне достаточно битов для работы с. Я мог затем сослаться на каждое булево значение с помощью указателя в нотации массива:

pStatus[element]

элемент обращается к байтам, не битам. Вы хотите что-то как:

pStatus[element/8] & (1 << (element % 8))
7
ответ дан 3 December 2019 в 13:30
поделиться

Ну, самый простой ответ должен был бы использовать calloc вместо malloc.

Это определяется для инициализации памяти, которую это выделяет нулю и может часто делать это при помощи приемов отображения страницы.

Это будет заботиться о Вашей проблеме инициализации памяти. Другая дюжина сообщений здесь, кажется, соответственно решает проблему индексации и то, что Вы иногда выделяете дополнительный байт (о, ужас!), таким образом, я не повторю их содержание здесь.

4
ответ дан 3 December 2019 в 13:30
поделиться

pStatus [элемент] не обращается к биту. Точный байт, который это получает, зависит от типа pStatus - я принимаю символ* или эквивалентный - таким образом, pStatus [элемент] получает Вас element'th байт.

Вы могли memset для установки на 0, да.

0
ответ дан 3 December 2019 в 13:30
поделиться

It amazes me that only one answer here mentions CHAR_BIT. A byte is often 8 bits, but not always.

0
ответ дан 3 December 2019 в 13:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: