C 中包含条件字段的结构
Structures containing conditional fields in C
我正在尝试实现一个协议标准,但我对他们的条件字段概念有些疑惑。它们被定义为根据某些条件存在或不存在的字段。他们给出的例子如下:
uint16 Pressure;
enum VehicleType { car = 0, motorbike = 1};
struct TirePressureInfo {
VehicleType type;
select (type)
{
case car:
Pressure frontLeft;
Pressure frontRight;
Pressure rearLeft;
Pressure rearRight;
case motorbike:
Pressure front;
Pressure rear;
}
}
无论如何,我不知道是否可以在 C 中完成这项工作,或者是否可能。反正我想不出要实现这个。需要注意的一件事是,这将在 Linux 内核模块中实现,所以我在那里也有点受限。
struct {
uint8 protocol_version;
ContentType type;
select (type) {
case unsecured :
opaque data<var>;
case signed, signed_partial_payload,
signed_external_payload:
SignedData signed_data;
case signed_wsa:
SignedWsa signed_wsa;
case encrypted :
EncryptedData encrypted_data;
case crl_request :
CrlRequest crl_request;
case crl :
Crl crl;
case other_value:
opaque data<var>;
}
} 1609Dot2Data;
struct {
SignerIdentifierType type;
select (type) {
case self: ;
case certificate_digest_with_ecdsap224 :
case certificate_digest_with_ecdsap256 :
HashedId8 digest;
opaque data<var>;
case certificate:
Certificate certificate;
case certificate_chain:
Certificate certificates<var>;
case certificate_digest_with_other_algorithm :
Signer signer;
PKAlgorithm algorithm;
HashedId8 digest;
case other_value:
opaque id<var>;
}
} SignerIdentifier;
您可以使用 union
:
uint16 Pressure;
enum VehicleType { CAR = 0, MOTORBIKE = 1};
struct TirePressureInfo {
VehicleType type;
union {
struct {
Pressure frontLeft;
Pressure frontRight;
Pressure rearLeft;
Pressure rearRight;
} car;
struct {
Pressure front;
Pressure rear;
} motorbike;
} data;
};
那么你可以这样设置:
struct TirePressureInfo info;
info.type = CAR;
info.data.car.frontLeft = 35;
info.data.car.frontRight = 35;
info.data.car.rearLeft = 32;
info.data.car.rearRight = 32;
或者如果你想定义一个 MOTORBIKE
:
struct TirePressureInfo info;
info.type = MOTORBIKE;
info.data.motorbike.front = 38;
info.data.motorbike.rear = 40;
当你阅读它时,你应该检查 type
:
switch ( info.type ) {
case CAR:
/* read info.data.car fields */
break;
case MOTORBIKE:
/* read info.data.motorbike fields */
break;
default:
/* Some data integrity problem */
}
如果您确定一次只需要 struct car
或 struct motorbike
(取决于 type
的值),那么就没有必要浪费 space 通过让每个 TirePressureInfo
包含 struct car
的字段和 struct motorbike
的字段。使用 union
会使 struct car
和 struct motorbike
在内存中占据相同的位置。 union
的实际大小是 greater of the two。这只是为您提供了不同的方式来读取和写入内存中的同一位置。
我正在尝试实现一个协议标准,但我对他们的条件字段概念有些疑惑。它们被定义为根据某些条件存在或不存在的字段。他们给出的例子如下:
uint16 Pressure;
enum VehicleType { car = 0, motorbike = 1};
struct TirePressureInfo {
VehicleType type;
select (type)
{
case car:
Pressure frontLeft;
Pressure frontRight;
Pressure rearLeft;
Pressure rearRight;
case motorbike:
Pressure front;
Pressure rear;
}
}
无论如何,我不知道是否可以在 C 中完成这项工作,或者是否可能。反正我想不出要实现这个。需要注意的一件事是,这将在 Linux 内核模块中实现,所以我在那里也有点受限。
struct {
uint8 protocol_version;
ContentType type;
select (type) {
case unsecured :
opaque data<var>;
case signed, signed_partial_payload,
signed_external_payload:
SignedData signed_data;
case signed_wsa:
SignedWsa signed_wsa;
case encrypted :
EncryptedData encrypted_data;
case crl_request :
CrlRequest crl_request;
case crl :
Crl crl;
case other_value:
opaque data<var>;
}
} 1609Dot2Data;
struct {
SignerIdentifierType type;
select (type) {
case self: ;
case certificate_digest_with_ecdsap224 :
case certificate_digest_with_ecdsap256 :
HashedId8 digest;
opaque data<var>;
case certificate:
Certificate certificate;
case certificate_chain:
Certificate certificates<var>;
case certificate_digest_with_other_algorithm :
Signer signer;
PKAlgorithm algorithm;
HashedId8 digest;
case other_value:
opaque id<var>;
}
} SignerIdentifier;
您可以使用 union
:
uint16 Pressure;
enum VehicleType { CAR = 0, MOTORBIKE = 1};
struct TirePressureInfo {
VehicleType type;
union {
struct {
Pressure frontLeft;
Pressure frontRight;
Pressure rearLeft;
Pressure rearRight;
} car;
struct {
Pressure front;
Pressure rear;
} motorbike;
} data;
};
那么你可以这样设置:
struct TirePressureInfo info;
info.type = CAR;
info.data.car.frontLeft = 35;
info.data.car.frontRight = 35;
info.data.car.rearLeft = 32;
info.data.car.rearRight = 32;
或者如果你想定义一个 MOTORBIKE
:
struct TirePressureInfo info;
info.type = MOTORBIKE;
info.data.motorbike.front = 38;
info.data.motorbike.rear = 40;
当你阅读它时,你应该检查 type
:
switch ( info.type ) {
case CAR:
/* read info.data.car fields */
break;
case MOTORBIKE:
/* read info.data.motorbike fields */
break;
default:
/* Some data integrity problem */
}
如果您确定一次只需要 struct car
或 struct motorbike
(取决于 type
的值),那么就没有必要浪费 space 通过让每个 TirePressureInfo
包含 struct car
的字段和 struct motorbike
的字段。使用 union
会使 struct car
和 struct motorbike
在内存中占据相同的位置。 union
的实际大小是 greater of the two。这只是为您提供了不同的方式来读取和写入内存中的同一位置。