我struct现有的计划非常重要.该结构包括大量的位域.
我希望保存它的一部分(例如,150个中的10个字段).
我用来保存子类的示例代码是:
typedef struct {int a;int b;char c} bigstruct;
typedef struct {int a;char c;} smallstruct;
void substruct(smallstruct *s,bigstruct *b) {
s->a = b->a;
s->c = b->c;
}
int save_struct(bigstruct *bs) {
smallstruct s;
substruct(&s,bs);
save_struct(s);
}
Run Code Online (Sandbox Code Playgroud)
我也希望选择它的哪一部分不会太麻烦,因为我希望时不时地改变它.我之前介绍的天真的方法是非常脆弱和不可维护的.当扩展到20个不同的字段时,您必须更改smallstruct和在substruct函数中的字段.
我想到了两种更好的方法.不幸的是,两者都要求我使用一些外部的CIL工具来解析我的结构.
第一种方法是自动生成substruct函数.我只是设置结构smallstruct,并有一个程序可以解析它并substruct根据中的字段生成函数smallstruct.
第二种方法是构建(使用C解析器)关于的元信息bigstruct,然后编写一个允许我访问结构中特定字段的库.这就像Java的类反射的临时实现.
例如,假设没有struct-alignment,对于struct
struct st {
int a;
char c1:5;
char c2:3;
long d;
}
Run Code Online (Sandbox Code Playgroud)
我将生成以下元信息:
int field2distance[] = {0,sizeof(int),sizeof(int),sizeof(int)+sizeof(char)}
int field2size[] = …Run Code Online (Sandbox Code Playgroud) 嗯...为什么我打印sizeof(struct MyStruct)时输出3(而不是2)代码呢?
#pragma pack(push, 1)
struct MyStruct
{
unsigned char a : 6;
union
{
struct
{
unsigned int b : 9;
};
};
};
#pragma pack(pop)
Run Code Online (Sandbox Code Playgroud)
如果它很重要,我在Windows 7 x64上运行MinGW GCC 4.5.0,但老实说,结果对我来说很奇怪,我不认为编译器和操作系统在这里太重要了.:\
位域的典型用法是声明小于8位的空间有效变量.我不明白的是将这些位声明为short,int,long,bool等的值.例如
typedef struct{
int first:3,
short second:3,
char third:3
} somestruct;
Run Code Online (Sandbox Code Playgroud)
在上述情况下,所有3个变量,即第一,第二和第三变量都是3位长.将变量首先声明为int,将第二个声明为short,将第三个声明为char的值是多少?
或者,为什么甚至需要数据类型?我应该能够将上述声明为
typedef struct{
first:3,
second:3,
third:3
} modifiedstruct;
Run Code Online (Sandbox Code Playgroud)
modifiedstruct假定变量first,second和third没有数据类型.解释3位的字符,数字或浮动应该是责任的责任的东西别人.
Linux上的gcc和g ++都允许上述行为.
是否可以将包含位字段的C风格结构编组到C#结构中,或者是否必须将其编组为基本类型然后执行位掩码?
例如,我想从这样的C风格结构编组:
struct rgb16 {
unsigned int R : 4;
unsigned int G : 5;
unsigned int B : 4;
}
Run Code Online (Sandbox Code Playgroud)
并将其编组到这样的事情上:
[StructLayout(LayoutKind.Sequential)]
public struct Rgb16 {
public byte R;
public byte G;
public byte B;
}
Run Code Online (Sandbox Code Playgroud) 假设我的项目包含来自第三方库的标题,其中包含:
struct foo {
signed int x:4;
};
Run Code Online (Sandbox Code Playgroud)
如果不假设位字段总是具有宽度4,并且不依赖于实现定义的行为,那么如何确定可以存储在成员中的最大值x?
我搜索过的每一本书,互联网上的每个教程以及SO上的每一个问与答都说,位域必须是整数类型。这是为什么?
以下bit field示例代码来自此处.它声称存储效率更高.但我想知道编译器如何处理位字段?
我猜的C编译器必须生成逐位操作额外的指令.因此,尽管数据大小减小,但代码大小也会增加.
任何熟悉C编译器的人都可以解释一下吗?
#include <stdio.h>
// A space optimized representation of date
struct date
{
// d has value between 1 and 31, so 5 bits
// are sufficient
unsigned int d: 5;
// m has value between 1 and 12, so 4 bits
// are sufficient
unsigned int m: 4;
unsigned int y;
};
int main()
{
printf("Size of date is %d bytes\n", sizeof(struct date));
struct date dt = {31, 12, 2014}; …Run Code Online (Sandbox Code Playgroud) 我有一个C结构定义为:
struct my_c_s {
u_char *ptr;
unsigned flag_a:1;
unsigned flag_b:1;
int some_num;
}
Run Code Online (Sandbox Code Playgroud)
怎么会flag_a和flag_b代表?
#[repr(C)]
pub struct my_rust_s {
pub ptr: *const u_char,
//pub flag_a: ?,
//pub flag_b: ?,
pub some_num: ::libc::c_int,
}
Run Code Online (Sandbox Code Playgroud)
我可以将它们声明为 或者整个事情需要是一个具有单个字段的位集合,然后我将它们用位掩码?bools吗?
例如 pub flag_bits: ::libc::c_uint,
I wanted to implement LFSR(linear feedback shift registers) in C to generate random bits. When I try to modify an individual bit or just assign a short value to memory block, all the bits set to 1. How can I stop this from happening?
struct lfsr{
//...
union{
unsigned short ff_0 : 1;
unsigned short ff_1 : 1;
//...
unsigned short ff_f : 1;
unsigned short ff;
}flip_flops;
};
int main() {
struct lfsr gen;
gen.flip_flops.ff = 1; //all the …Run Code Online (Sandbox Code Playgroud) 请考虑以下实验性Ada程序,该程序尝试创建具有定义明确的位字段的32位记录,创建一个并将其输出到文件流...
with System;
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Streams.Stream_Io; use Ada.Streams.Stream_Io;
procedure Main is
type Bit is mod (2 ** 1);
type Opcode_Number is mod (2 ** 4);
type Condition_Number is mod (2 ** 4);
type Operand is mod (2 ** 9);
type RAM_Register is
record
Opcode : Opcode_Number;
Z : Bit;
C : Bit;
R : Bit;
I : Bit;
Cond : Condition_Number;
Rsvd_1 : Bit;
Rsvd_2 : Bit;
Dest : Operand;
Src : Operand;
end record;
for RAM_Register …Run Code Online (Sandbox Code Playgroud)