Pointer ke elemen di dalam struktur (C)

Oct 20 2020

Untuk platform Arduino, saya ingin menerima 16 byte dan memasukkan nilainya ke dalam sebuah struktur. Saat ini saya memiliki kode ini

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 ) ;
}

Struct 'Sections' belum ada tetapi akan berisi 16 variabel dengan tipe uint8_t. Meskipun ini akan bekerja dengan baik, saya lebih suka menggunakan for-loop.

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 ) ;
}

Saya bukan orang baru dalam hal petunjuk, tetapi saya belum menggunakan contoh khusus ini dan lebih baik aman daripada menyesal.

Pertanyaan saya: Apakah saya menggunakan pointer dengan benar dalam contoh ini? Dan jika tidak, bagaimana seharusnya?

Sebuah awnser dengan "ya" saja sudah cukup untuk saya. Terima kasih sebelumnya.

EDIT: Saya mengetahui struktur padding dalam penyimpanan, struct akan berisi variabel persis 16x uint8_t. Namun mungkin menjadi masalah bahwa kompilator dapat mengatur ulang penyimpanan variabel struct dalam urutan acak.

Juga hal penting yang mungkin harus saya sebutkan. Itu tidak ada di contoh. Tetapi fungsi storeLayout (& newSection) itu akan menyalin konten dari struktur lokal ini ke objek struktur yang merupakan bagian dari array.

Jadi akan ada larik 64 struktur ini (masing-masing berisi 16 variabel uint8_t)

Apakah ada cara untuk menggunakan contoh for-loop ini tanpa harus mengubah variabelnya menjadi array? (untuk menangani perilaku compiler acak untuk penyimpanan variabel)

Jawaban

1 AliMirghasemi Oct 20 2020 at 14:12

saya pikir jalan Anda benar kode Anda tidak apa-apa

Anda dapat melihat jawaban ini untuk mengirim dan menerima Paket

dan contoh berikut menunjukkan cara menunjuk ke item struct

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;

dan jika Anda ingin mengabaikan padding di struct tambahkan kode berikut

#pragma pack(push, 1)

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

#pragma pack(pop)

Anda dapat melihat hasil dengan ukuran cetak (Paket)

  • Ingat tidak ada padding di sistem 8bit seperti Arduino UNO atau AVR, tetapi padding di ARM MCU ada