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 carstruct motorbike(取决于 type 的值),那么就没有必要浪费 space 通过让每个 TirePressureInfo 包含 struct car 的字段和 struct motorbike 的字段。使用 union 会使 struct carstruct motorbike 在内存中占据相同的位置。 union 的实际大小是 greater of the two。这只是为您提供了不同的方式来读取和写入内存中的同一位置。