Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
`联合定义中的sizeof`struct_C_Struct_Unions_C11 - Fatal编程技术网

`联合定义中的sizeof`struct

`联合定义中的sizeof`struct,c,struct,unions,c11,C,Struct,Unions,C11,要按字节访问结构,我使用的是联合 typedef struct { char hi; char lo; } range; union { range by_name; char as_bytes[sizeof(range)]; } U1; char use_U1(void){ char c = U1.as_bytes[0]; return U1.by_name.hi; } 问题1:是否可以跳过typedef?像这样: union {

要按字节访问
结构
,我使用的是
联合

typedef struct {
    char hi;
    char lo;
} range;

union {
    range by_name;
    char as_bytes[sizeof(range)];
} U1;

char use_U1(void){
    char c = U1.as_bytes[0];
    return U1.by_name.hi;
}
问题1:是否可以跳过
typedef
?像这样:

union {
    struct {
        char hi;
        char lo;
    } by_name;
    char as_bytes[2]; //want sizeof()
} U2;
未编译的
字符(按字节[sizeof(按名称)]
不会编译:
错误:此处未声明“by_name”(不在函数中)

问题2:相同,但具有匿名结构,以避免在使用时按名称键入

union {
    struct {
        char hi;
        char lo;
    };
    char as_bytes[2]; //want sizeof()
} U3;

int use_U3(void){
    char c = U3.as_bytes[0];
    return U3.hi; // anonymous structure
}

阅读到目前为止:,

您可以为
结构提供一个标记名并使用它

union {
    struct inner {
        char hi;
        char lo;
    } by_name;
    char as_bytes[sizeof(struct inner)];
} U2;

请注意,这确实要求内部结构具有名称。如果没有名称,则必须省略标记。

您可以为
struct
指定标记名称并使用该名称

union {
    struct inner {
        char hi;
        char lo;
    } by_name;
    char as_bytes[sizeof(struct inner)];
} U2;

请注意,这确实要求内部结构具有名称。如果没有名称,则必须省略标记。

您不能采用匿名类型的大小,因此只需将其设置为非匿名:

union 
{
    struct range// <<< give it a tag here
    { 
        char hi;
        char lo;
    } by_name;

    char as_bytes[sizeof(struct range)]; // <<< Take sizeof here

} U2;

您不能采用匿名类型的大小,因此只需将其设置为非匿名:

union 
{
    struct range// <<< give it a tag here
    { 
        char hi;
        char lo;
    } by_name;

    char as_bytes[sizeof(struct range)]; // <<< Take sizeof here

} U2;

更简单的版本不可移植(如果您计划使用非gcc或mvsc编译器):


更简单的版本不可移植(如果您计划使用非gcc或mvsc编译器):


为什么要使用联合而不是将地址强制转换为
char*
?(与问题本身相切)@MadPhysician,这只是一个简短的假例子。真正的结构要长得多。这难道不会使
char*
cast更具吸引力吗?一般来说,使用匿名结构和联合是一种糟糕的编程实践。这是(出于多种原因,包括)大多数调试器无法在没有“标记”名称的情况下显示单个字段。尽管值得注意的是,使用“草率键入”
char
存储原始二进制数据是一个可怕的想法,因为实现定义了签名。专业代码总是使用
uint8\u t
。为什么要使用联合而不是将地址强制转换为
char*
?(与问题本身相切)@MadPhysician,这只是一个简短的假例子。真正的结构要长得多。这难道不会使
char*
cast更具吸引力吗?一般来说,使用匿名结构和联合是一种糟糕的编程实践。这是(出于多种原因,包括)大多数调试器无法在没有“标记”名称的情况下显示单个字段。尽管值得注意的是,使用“草率键入”
char
存储原始二进制数据是一个可怕的想法,因为实现定义了签名。专业代码总是使用
uint8\u t
。您可以通过重复结构定义来匿名并满足问题的要求,以避免
typedef
union{struct{char hi;char lo;};char as_bytes[sizeof(struct{char hi;char lo;})]}U2。不过,我认为他们可能更愿意重复
typedef
。您可以使其匿名,并通过重复结构定义来满足问题的要求以避免
typedef
union{struct{char hi;char lo;};char as_bytes[sizeof(struct{char hi;char lo;})];}U2。不过,我认为他们可能更愿意重复
typedef
。我认为,嵌套typedef的一个小用途可能是限制
范围的范围。对我来说很有用。@Xpector第一个非typdef也有同样的优势。我的观点仅仅是,创建typedef别名只是为了避免在有限的范围内键入“struct”,而且它只出现一次,这样做没有什么意义。可能有其他成员使用相同的类型。我认为嵌套typedef的一个小用途可能是限制
范围的范围。对我来说很有用。@Xpector第一个非typdef也有同样的优势。我的观点仅仅是,创建typedef别名只是为了避免在有限的范围内键入“struct”,而且它只出现一次,这样做没有什么意义。可能存在使用相同类型的其他成员。