我有这些结构体
typedef struct DeviceState_s {
uint32_t Function_Type;
uint8_t Left_Trigger;//byte [1]#9 left analog trigger
uint8_t Right_Trigger;//byte [2]#10 right analog trigger
uint8_t Buttons_1;//byte [3]#11 1----XY(1/Z) ..X and Y are the bits representing the buttons state (1 for unpress 0 for press) the last bit is z if the controller supports it.
uint8_t Buttons_2;//byte [4]#12 PR PL PD PU start A B (1/C) PR=pad right same for the rest and the bit marked as one is c if the controller supports it.
uint8_t Analog_a1;//byte [5]#13 useless in original controller
uint8_t Analog_a2;//byte [6]#14 useless in original controller
uint8_t Analog_Y;//byte [7]#15 joystick Y axis movement
uint8_t Analog_X;//byte [8]#16 joystick X axis movement
} DeviceState;
typedef struct DeviceStatus_s {
uint32_t Function;
uint32_t DeviceID[3];
uint8_t AreaCode; //1
uint8_t ConnectorDirection; //1
char ProductName[30];
char ProductLicense[60];
uint16_t StandbyPower; //2
uint16_t MaxPower; //2
} DeviceStatus;
typedef struct Status_FPacket_s {
PacketHeader Header; //4
DeviceStatus Status //112
} Status_FPacket;
static Status_FPacket Status_Packet;
字符串
然后再让它们跳动。但是没有必要每次都填充状态,它总是相同的。我想也许有一个是这样的。
typedef struct Status_FPacket_s {
PacketHeader Header; //4
DeviceStatus Status //112
= {
.Function = FUNC_CONTROLLER,
.DeviceID[0] = 0xffff06fe,
.DeviceID[1] = 0x0000ffff,
.DeviceID[2] = 0x00000000,
.AreaCode = 0xff,
.ConnectorDirection = 0,
.ProductName =0,
.ProductLicense =0,
.StandbyPower = (430>>8) | (430<<8),
.MaxPower = (500>>8) | (500<<8),
};
} Status_FPacket;
型
但那没用也许我需要用我自己的类型?
/添加AbeMonk的建议//
typedef struct DeviceStatus_s {
uint32_t Function;
uint32_t DeviceID[3];
uint8_t AreaCode; //1
uint8_t ConnectorDirection; //1
char ProductName[30];
char ProductLicense[60];
uint16_t StandbyPower; //2
uint16_t MaxPower; //2
} DeviceStatus;
static DeviceStatus controllerStatus =
{
.Function=FUNC_CONTROLLER,
.DeviceID[0]= 0xffff06fe,
.DeviceID[1]= 0x0000ffff,
.DeviceID[2] = 0x00000000,
.AreaCode = 0xff,
.ConnectorDirection = 0,
.ProductName = "....";
.ProductLicense "....";
.StandbyPower = (430>>8) | (430<<8),
.MaxPower = (500>>8) | (500<<8),
};
型
那就晚点再做吧
Status_Packet.Status = controllerStatus;
我用来设置琴弦的东西是
strncpy(Status_Packet.Status.ProductName,“text here”,sizeof(Status_Packet.Status.ProductName));
不知道如何做到这一点没有strncpy。
1条答案
按热度按时间dphi5xsq1#
C不是面向对象的语言。虽然C中的结构体可以用来对数据进行分组,但它们的功能并没有超出这一范围--换句话说,它们提供的功能和抽象级别远不及C++类。然而,这并不意味着不可能在C中实现或至少接近理论上的“静态”结构成员。使用指针和全局变量,可以实现类似的功能:
首先,你需要初始化一个全局变量:
字符串
然后,在将包含此“静态”成员的结构实现中,您将声明一个指针。这意味着全局变量将不需要跨示例复制,并且如果被一个示例修改,则将为所有示例更改:
型
当然,将地址存储在指针中会占用空间(尽管比按值复制要少得多)。然而,我想不出一种方法来避免这一点(至少没有更明显的解决方案,即在所有需要全局变量的情况下直接使用全局变量;但是,我假设如果它足够话,您已经这样做了)。
现在,你所需要做的就是创建一个“构造函数”(从某种意义上说,我们试图模拟类),每次初始化Status_FPacket对象时都会调用它:
型
然后当你想初始化Status_FPacket对象时:
型
可能的微小修改
我知道全局变量被认为是不好的做法。有一种方法可以解决这个问题,虽然可能有我不知道的重复(我已经尝试过了,它似乎工作)。你可以在“constructor”函数中创建一个静态变量,如下所示:
型
C中的Static function variables是特殊的--它们在所有的函数调用中都保留在内存中的位置,并在应用程序的整个生命周期中存在。这意味着静态global_status变量实际上 * 每次 * 调用“构造函数”时 * 都是同一个示例。
避免使用strcpy
至于使用strcpy,完全可以避免这种不必要的开销。我假设您不会在内部修改productName和productLiscense的值。在这种情况下,你可以将它们声明为常量char指针而不是数组,如下所示:
型
你现在可以直接使用**=**将字符串赋值给它们,因为它们是常量。