2012-10-10 5 views
10

Probabilmente una domanda ingenua - ho programmato 20 anni fa e da allora non ho più codificato. Il mio ricordo di come il C preprocessor opere è atrofizzata in modo significativo da allora ...Formato array per #define (preprocessore C)

Sto scrivendo un programma molto semplice C e sto cercando di dichiarare un paio di matrici globali statiche, ma la dimensione del arrays sarebbe dipendente (su un modo non banale) su una variabile MODE. Qualcosa come l'esempio semplificato di seguito.

Due punti veloci: So che potrei solo le dimensioni del arrays secondo la più grande dimensione necessaria per qualsiasi MODE, ma io non voglio che perché (a differenza del semplice esempio di seguito) a volte una manciata di queste dimensioni sono sarà estremamente grande mentre gli altri sono piccoli.

Inoltre, voglio utilizzare array globali definiti staticamente, anziché allocarli dinamicamente in fase di runtime. Voglio che il compilatore abbia le dimensioni al momento della compilazione.

//** Simplified example of what I'd like to do **//  
#define SIZE_LIST_1[5] = {2, 7, 23, 33, 12, 76} // I don't think this is valid syntax 
#define SIZE_LIST_2[5] = {11, 65, 222, 112, 444} 

#define MODE 4 
#define S1 SIZE_LIST_1[MODE] 
#define S2 SIZE_LIST_2[MODE] 

int a[S1], b[S2]; 
+0

'int SIZE_LIST_1 [5] = {2,7 ... 76};' –

+1

Le macro sono sostituzioni. – Jack

+0

Non vedo cosa intendi con [S1]. cosa stai cercando di fare lì? –

risposta

10

È necessario definire un gruppo di macro di supporto prima di poter fare questo in modo semplice:

#define CONCAT(A,B)   A ## B 
#define EXPAND_CONCAT(A,B) CONCAT(A, B) 

#define ARGN(N, LIST)  EXPAND_CONCAT(ARG_, N) LIST 
#define ARG_0(A0, ...)  A0 
#define ARG_1(A0, A1, ...) A1 
#define ARG_2(A0, A1, A2, ...)  A2 
#define ARG_3(A0, A1, A2, A3, ...) A3 
#define ARG_4(A0, A1, A2, A3, A4, ...)  A4 
#define ARG_5(A0, A1, A2, A3, A4, A5, ...) A5 
#define ARG_6(A0, A1, A2, A3, A4, A5, A6, ...)  A6 
#define ARG_7(A0, A1, A2, A3, A4, A5, A6, A7, ...) A7 
#define ARG_8(A0, A1, A2, A3, A4, A5, A6, A7, A8, ...)  A8 
#define ARG_9(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, ...) A9 
#define ARG_10(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, ...) A10 

/* above should be in a pp_helper.h header file or some such */ 

#define SIZE_LIST_1 (2, 7, 23, 33, 12, 76) 
#define SIZE_LIST_2 (11, 65, 222, 112, 444, 1000) 

#define S1 ARGN(MODE, SIZE_LIST_1) 
#define S2 ARGN(MODE, SIZE_LIST_2) 

#define MODE 4 

int a[S1], b[S2]; 

Ci sono un sacco di le 'librerie' del preprocessore che puoi ottenere con il codice boilerplate (boost PP, P99), o puoi semplicemente creare il tuo. Il problema principale è che è necessario definire le macro ARG in base al maggior numero di argomenti che si desidera gestire.

7

Probabilmente la migliore che puoi fare è qualcosa di simile:

#define SIZE_LIST_1_0 2 
#define SIZE_LIST_1_1 7 
#define SIZE_LIST_1_2 23 
#define SIZE_LIST_1_3 33 
#define SIZE_LIST_1_4 12 

#define SIZE_LIST_2_0 11 
#define SIZE_LIST_2_1 65 
#define SIZE_LIST_2_2 222 
#define SIZE_LIST_2_3 112 
#define SIZE_LIST_2_4 444 

#define MODE 4 

#define S1 SIZE_LIST_1_##MODE 
#define S2 SIZE_LIST_2_##MODE 

int a[S1], b[S2]; 
+0

Grazie, Paul, è un po 'caotico, ma potrebbe risolvere il problema. Non sapevo che avresti potuto farlo. Lo prendo non ci sono modi 'più eleganti' di farlo? – user1735592

+0

No: il preprocessore è davvero molto limitato e non è stato progettato per questo tipo di abuso. Non sono sicuro del motivo per cui questa risposta abbia ottenuto un voto negativo anonimo - non è molto elegante ma risolve il problema. Oh beh ... –

+1

Non vedo neanche il motivo per cui dovrebbe essere votato. Grazie ancora per l'idea. – user1735592

3

temo non c'è questa possibilità.

suggerisco il seguente approccio invece:

#define MODE 0 

#define DECLARE_ARRAYS_WITH_SIZES(S1, S2, S3) \ 
    int arr1[S1]; \ 
    int arr2[S2]; \ 
    int arr3[S3]; 

#if MODE == 0 
DECLARE_ARRAYS_WITH_SIZES(3, 6, 7) 
#elif MODE == 1 
DECLARE_ARRAYS_WITH_SIZES(8, 2, 1) 
#endif