簡體   English   中英

在C中的數組定義中使用宏

[英]Use of macros in array definition in C

我是C語言的新手,並用它來編程Nordic nrf52芯片。 我相信我的問題是通用C語言,而不是應用程序。

我正在使用芯片SDK中預定義的宏設置結構數組。 在數組初始化中使用這些宏有效,但逐個元素無效。
因此,以下工作:

nrf_twi_mngr_transfer_t transfers_1[2] = { \
                                    NRF_TWI_MNGR_WRITE(MSBARO5X_0_ADDR , &reg_addr[1], 1, NRF_TWI_MNGR_NO_STOP), \
                                    NRF_TWI_MNGR_READ (MSBARO5X_0_ADDR , &p_buffer[0], sizeof(p_buffer), 0)
                            };      

哪里:

typedef struct {
    uint8_t * p_data;     ///< Pointer to the buffer holding the data.
    uint8_t   length;     ///< Number of bytes to transfer.
    uint8_t   operation;  ///< Device address combined with transfer direction.
    uint8_t   flags;      ///< Transfer flags (see @ref NRF_TWI_MNGR_NO_STOP).
} nrf_twi_mngr_transfer_t;

NRF_TWI_WRITE和_READ是使用其他宏的宏,例如:

#define NRF_TWI_MNGR_WRITE(address, p_data, length, flags) \
    NRF_TWI_MNGR_TRANSFER(NRF_TWI_MNGR_WRITE_OP(address), p_data, length, flags)

使用

#define NRF_TWI_MNGR_WRITE_OP(address)      (((address) << 1) | 0)

#define NRF_TWI_MNGR_TRANSFER(_operation, _p_data, _length, _flags) \
{                                      \
    .p_data    = (uint8_t *)(_p_data), \
    .length    = _length,              \
    .operation = _operation,           \
    .flags     = _flags                \
}

我想做的是更改此數組中的單個項目,例如:

transfers_1[0] = NRF_TWI_MNGR_WRITE(MSBARO5X_0_ADDR , &reg_addr[1], 1, NRF_TWI_MNGR_NO_STOP);

但是,當我這樣做時,出現錯誤“期望表達式”。

在定義語句中也定義了MSBARO5X_0_ADDR:#define MSBARO5X_0_ADDR 0x76

如果我在上述任何代碼中用一個變量替換了該變量,則會收到相同的“期望表達式”錯誤。 我懷疑我遇到的兩個問題是由於我同樣缺乏理解。 因此,請原諒我將兩者合並在一個帖子中。

因此,問題是:-為什么我會收到此錯誤? -是否可以更改陣列中的單個項目,如果可以,如何更改? -是否可以使用變量代替MSBARO5X_ADDR,如果可以,怎么辦?

非常感謝!

最終,宏擴展為括號括起的初始化程序。 這樣的東西不是表達式,因此不能用作普通賦值的右邊(賦值和初始化是不同的事物)。 它可以作為較大的初始化程序的一部分,但不能用作未修改的嘗試方式。

但是,一切並沒有丟失。 初始化程序的語法暗含支持。 因此,我們可以使用一個技巧。 可以將結構對象彼此分配。 所以我們只需要從某個地方獲取一個對象。 我們可以使用復合文字來創建所述對象:

transfers_1[0] = (nrf_twi_mngr_transfer_t)NRF_TWI_MNGR_WRITE(/*Your arguments*/);

如果在聲明結構時定義結構的值,則編譯器將從聲明中推斷出結構的類型。 因此,這里將進行編譯:

struct coordinates {
  int x;
  int y;
};

struct coordinates origin = { 10, 20 }; // This is OK

但是,如果為先前聲明的變量分配值,則編譯器無法推斷其類型。 這段代碼不會編譯:

struct coordinates origin;
origin = { 10, 20 }; // ERROR! The type of the rvalue is unknown!

類型是未知的,因為兩個結構在C中不僅僅因為它們具有相同的成員而等效。 例如,這在C語言中是合法的:

struct coordinates {
  int x;
  int y;
};

struct dayOfYear {
  int day;
  int month;
};

現在{ 5, 8 }是什么? 坐標(5/8)還是8月5日? 可能兩者都有。 他的編譯器只知道它是{ int, int }類型的結構。 但這並沒有在C語言中定義類型。在某些語言中,以下是可能的,但在C語言中是不可能的:

struct dayOfYear date = { 2, 3 };
struct coordinates cords = date; // ERROR!

盡管兩個結構均為{ int, int }類型,但對於編譯器而言, struct dayOfYearstruct coordinates是兩種完全不同struct dayOfYear相關的數據類型。

如果要聲明硬編碼的結構值,則需要告訴編譯器哪種結構是:

struct coordinates origin;
origin = (struct coordinates){ 10, 20 }; // This is OK

您的NRF_TWI_MNGR_TRANSFER定義了一個硬編碼的結構,但是只有當您在定義中使用它時,編譯器才能知道類型。 如果嘗試將其用作分配,則需要強制轉換為正確的類型。

transfers_1[0] = (nrf_twi_mngr_transfer_t)NRF_TWI_MNGR_WRITE(MSBARO5X_0_ADDR , &reg_addr[1], 1, NRF_TWI_MNGR_NO_STOP);

即使它具有相同的語法,也不是強制轉換。 實際上,這只是在告訴編譯器如何解釋以下數據。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM