c - 指向结构内元素的指针 ( C )

标签 c arduino embedded atmega

对于 arduino 平台,我想接收 16 个字节并将它们的值填充到一个结构中。目前我有这段代码

if( Serial.available() >= sizeof( newSection ) ) { // if atleast one full struct is received

    Sections newSection ;                   // declare a local Sections object and fill it
    
    newSection.leftSensor = Serial.read() ;
    newSection.leftSensor = Serial.read() ; // the other variables don't exist yet
    newSection.leftSensor = Serial.read() ;
    newSection.leftSensor = Serial.read() ;
    newSection.leftSensor = Serial.read() ;
    newSection.leftSensor = Serial.read() ;
    newSection.leftSensor = Serial.read() ;
    newSection.leftSensor = Serial.read() ;
    newSection.leftSensor = Serial.read() ;
    newSection.leftSensor = Serial.read() ;
    newSection.leftSensor = Serial.read() ;
    newSection.leftSensor = Serial.read() ;
    newSection.leftSensor = Serial.read() ;
    newSection.leftSensor = Serial.read() ;
    newSection.leftSensor = Serial.read() ;
    newSection.leftSensor = Serial.read() ;
    
    storeLayout( &newSection ) ;
}

“Sections”结构尚不存在,但它将包含 16 个 uint8_t 类型的变量。虽然这可能会很好地工作,但我更喜欢使用 for 循环。

if( Serial.available() >= sizeof( newSection ) ) { // if atleast one full struct is received

    Sections newSection ;                   // declare a local sectuin variable and fill it
    
    uint8_t *ptr ;
    ptr = &newSection.leftSensor ;          // let pointer point to the first variable of local struct object < -???
    
    for( byte i = 0 ; i < sizeof( newSection ) ; i ++ ) {
        *ptr = Serial.read() ;
        ptr ++ ;
    }
    
    storeLayout( &newSection ) ;
}

我对指针并不陌生,但我还没有使用过这个特定的例子,安全总比抱歉好。

我的问题:我在这个例子中是否正确使用了指针? 如果不是,它应该是什么样子?

一个只有"is"的遮阳篷对我来说就足够了。 提前致谢。

编辑: 我知道存储中的结构填充,该结构将精确包含 16x uint8_t 变量。然而,编译器可能会以随机顺序重新安排结构变量的存储,这可能是一个问题。

我也许应该提到的同样重要的事情。它不在示例中。但是该函数 storeLayout( &newSection ) 会将此局部结构的内容复制到作为数组一部分的结构对象。

所以会有一个包含 64 个结构的数组(每个结构包含 16 个 uint8_t 变量)

是否有方法可以使用这个例子的 for 循环而不必将它的变量转换为数组? (处理变量存储的随机编译器行为)

最佳答案

我认为你的路径是正确的你的代码没问题

可以看到this发送和接收数据包的应答

下面的例子展示了如何指向一个结构体

typedef struct {
    uint16_t X;
    uint8_t  Y;
    uint8_t  Z;
} Packet;

Packet mPacket;

uint8_t* pY = &mPacket.Y;
uint16_t* pX = &mPacket.X;

// point to whole struct and cast it to byte array 
uint8_t* pPacketBytes = (uint8_t*) &mPacket;

如果您想忽略结构中的填充,请添加以下代码

#pragma pack(push, 1)

// define your structs
typedef struct {
    uint16_t X;
    uint8_t  Y;
    uint8_t  Z;
} PacketNoPadding;

#pragma pack(pop)

打印 sizeof(Packet) 可以看到结果

  • 记住Arduino UNO或AVR等8位系统没有padding,但是ARM MCU有padding

关于c - 指向结构内元素的指针 ( C ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64440091/

相关文章:

将一个简单的哈希函数从 c 转换为 go

c - 多线程与单线程进程运行时

c++ - 重载函数调用 double 是不明确的

embedded - 通过 SPI 的芯片到芯片通信协议(protocol)

c - 单周期乘法和硬件除法是什么意思?

c - 如何发送带有变量声明的电子邮件

c++ - 从 'double' 转换为 'DWORD' ,可能会丢失数据

c++ - 在 Arduino 上重载流式传输

c - Arduino StackArray 不是全局的

c - 将 ESP8266 SDK 移植到 ESP32