簡體   English   中英

如何在C中創建結構文字的數組文字?

[英]How to create an array literal of struct literals in C?

我的目標是自動生成基於舊知識的系統的控制邏輯,該系統本質上是一系列數百個結構類似的if-then語句。 我們還希望通過某種反射來了解這些語句的屬性,數組文字有助於生成這些反射。

我在這里回顧了許多關於SO的答案,但是其中大多數是關於字符串文字數組的,這不是我想要實現的。

我正在嘗試制作一個X宏,它包含一個結構文字數組作為其參數之一,可用於初始化堆棧分配的數組變量。

這是一些未編譯的代碼,顯示了我的嘗試:

#include <stdio.h>

typedef enum qty_t {
    qty_None, qty_Some, qty_Many    
} qty_t;

typedef enum arg_t {
    arg_X, arg_Y, arg_Z
} arg_t;

typedef struct action_t {
    int id;
    qty_t quantity;
    arg_t argument;
} action_t;

/* a change is a sequence of actions, and a change identifier */
/* the outermost {} are the array, the inner ones being the structs */
#define CHANGES \
CHANGE(1, ({{.id=1,.quantity=qty_None,.argument=arg_X}, \
            {.id=2,.quantity=qty_Many,.argument=arg_Z}\
            }\
        )\
    )\
CHANGE(2, ({{1,qty_Some,arg_Y}}))

int main(void) {
    // your code goes here
#define CHANGE(change_id, actions) \
    action_t current_actions ## change_id[] = actions;

    CHANGES

#undef CHANGE
    return 0;
}

如何在CHANGE宏中放入結構常量的數組常量,特別是可用於初始化current_actions1變量的數組常量?

那個怎么樣 :

#define CHANGES \
CHANGE(1, {{.id=1,.quantity=qty_None,.argument=arg_X}, \
            {.id=2,.quantity=qty_Many,.argument=arg_Z}\
            }\
           \
    )\
CHANGE(2, {{.id=1,.quantity=qty_Some,.argument=arg_Y}})

int main(void) {
    // your code goes here
#define CHANGE(change_id, actions ...) \
    action_t current_actions ## change_id[] = actions;

    CHANGES

#undef CHANGE
    return 0;
}

我在CHANGES中刪除了括號,並在CHANGE中添加了...

該編譯和gcc -E foo.c給出:

   int main(void) {




        action_t current_actions1[] = {{.id=1,.quantity=qty_None,.argument=arg_X}, {.id=2,.quantity=qty_Many,.argument=arg_Z} }; action_t current_actions2[] = {{.id=1,.quantity=qty_Some,.argument=arg_Y}};


        return 0;
    }

不管是否有文字本身,都沒有“結構文字數組”之類的東西。 數組的元素可以是結構,您可以使用結構文字來初始化結構數組(yuck)的元素(包括數組文字),但數組的元素本身不是文字。 這聽起來可能(確實,可能是)是學究的,但是使用一致且正確的術語可以提高思想和溝通的清晰度。

實際上,您根本沒有使用結構文字或數組文字。 您只是在結構體的初始化程序內使用結構體初始化程序。 這已經稍微簡化了問題。

您的代碼的第一個問題是放在數組初始化程序周圍的CHANGE宏定義中的括號。 這些是每次CHANGE宏調用的第二個參數的一部分,因此,它們作為宏CHANGES的替換文本的一部分發出。 但是它們不是初始化器允許的語法的一部分,因此生成的代碼無效。

我假設首先要放在括號中,以避免初始化程序內部的逗號被解釋為分隔宏參數。 解決該問題的另一種方法(在這種情況下,至少要這樣)是使您定義CHANGE宏可變參數:

#define CHANGE(change_id, ...) \
    action_t current_actions ## change_id[] = __VA_ARGS__;

這使用C99中介紹的標准形式的可變參數宏為我解決了問題。

另一個更結構化的替代方法是為結構初始化程序添加宏,以使內部及其之間的逗號不影響宏參數標識。 例如,

#define FIRST_ACTION(i,q,a) {.id=i,.quantity=q,.argument=a}
#define ACTION(i,q,a) ,FIRST_ACTION(i,q,a)

#define CHANGES \
CHANGE(1, {\
    FIRST_ACTION(1,qty_None,arg_X)\
    ACTION(2,qty_Many,arg_Z)\
})\
CHANGE(2, {\
    FIRST_ACTION(1,qty_Some,arg_Y)\
})

// ...

#define CHANGE(change_id, actions) \
    action_t current_actions ## change_id[] = actions;

    CHANGES

當然,所有這些都假設您的情況下從X宏方法中可以獲得一些好的價值。 這至少需要在代碼的其他地方使用CHANGES宏。 在您呈現的內容中,沒有任何明顯的事物,但可以將其省略。 但是,我目前還不清楚,您的特定CHANGES宏提供了其他用途,而其他方法無法更好地滿足這一需求。

暫無
暫無

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

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