2015-09-08 2 views
3

Я попытался использовать битовые поля в структуре для некоторых значений, которым нужен только один или два бита вместо целого байта.Как добавить массив в структуру битового поля?

Мой код:

struct s_rdata { 
    signed int  p0:28; 
    signed int  p1:28; 
    signed int  p2:28; 
    unsigned int d0:17; 
    unsigned int d1:17; 
    unsigned int d2:17; 
    unsigned char data1:1; 
    unsigned char data2:1; 
} rdata; 

Таким образом, вы можете видеть, что есть переменные с именем p0 - p2, d0 - d2 и data1 - data2.

Теперь я хотел бы иметь их в массиве. Тем не менее, ни одна из этих линий не делает работу:

signed int p[3]:28; 
signed int p:28[3]; 

не Могу ли я добавить массив в список битового, массив signed int только нуждающийся в 28 бит на запись?

ответ

4

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

Вы можете иметь массив через struct с с одним членом битовом:

struct container { 
    signed int bitfield:7; 
} array[3]; 

но опять же, вы потеряете эффективность использования пространства, связанную с использованием битового.

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

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

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

+1

Будет *** [прагма-пакет] (https://msdn.microsoft.com/en-us/library/Aa273913%28v=VS.60%29.aspx) *** инструкции помогают с неэффективностью пространства, если переход со структурными массивами? – ryyker

+1

@ryyker, может быть. Сведения об эффектах '#pragma pack' специфичны для реализации.В тех случаях, когда это вообще имеет какой-либо эффект, конкретные виды использования могут или не могут помешать компилятору выложить структуры с внутренним или конечным дополнением за счет возможного смещения членов. Если вы не пытаетесь сопоставить тип 'struct' с конкретным, определяемым извне шаблоном данных, обычно лучше просто выложить элементы вручную с самого большого требования к выравниванию до наименьшего; это обычно избегает ввода внутренней прокладки, но все равно может быть завершающее дополнение. –

0

Я согласен с @ оценкой Джона в отношении космической неэффективности, но несмотря на это, здесь идея содержать содержимое битового поля в пределах структуры массива:

typedef struct 
{ 
    int A : 16; 
    int B : 16; 
} Struct1; 

typedef struct 
{ 
    Struct1 B;//bitfield struct 
    int array[10];//combined with array (of any legal type) 
} 

Вот пример заполнения массива с содержимое битном структуры:

typedef struct { 
    signed int  p0:28; 
    signed int  p1:28; 
    signed int  p2:28; 
    unsigned int d0:17; 
    unsigned int d1:17; 
    unsigned int d2:17; 
    unsigned char data1:1; 
    unsigned char data2:1; 
} RDATA; 


typedef struct { 
    int A[3]; 
    unsigned int B[3]; 
    unsigned char C[2]; 
} ARRAY; 

RDATA rdata = {//initialize instance of RDATA with data 
    28, 
    28, 
    28, 
    17, 
    17, 
    17, 
    1, 
    1 
}; 

int WriteToArray(ARRAY *a); 

int main(void) 
{ 
    ARRAY a; 
    WriteToArray(&a);//populate array with RDATA values 

    //ARRAY is now populated with bitfield values; 
    a.A[0]; 
    a.A[1]; 
    //and so on 

    return 0; 
} 

WriteToArray(ARRAY *a) 
{ 
    a->A[0]=rdata.p0;//using values initialized above 
    a->A[1]=rdata.p1; 
    a->A[2]=rdata.p2; 
    a->B[0]=rdata.d0; 
    a->B[1]=rdata.d1; 
    a->B[2]=rdata.d2; 
    a->C[0]=rdata.data1; 
    a->C[1]=rdata.data2; 
    return 0; 
} 

Вы можете также экспериментировать с pragma pack заявления смотреть на эффекты на пространстве, бушель t см. комментарий @ John в вашем сообщении для дополнительных соображений относительно прагмы и интервала.