2012-10-10 11 views
10

Wahrscheinlich eine naive Frage - ich programmierte vor 20 Jahren und habe seitdem nicht viel codiert. Meine Erinnerung an wie die C preprocessor Arbeiten hat sich seither deutlich verkümmert ...Array-Format für #define (C-Präprozessor)

ich ein sehr einfaches C Programm schreibe und ich versuche, ein paar statische globale Arrays zu erklären, aber die Größe des arrays wäre abhängig (auf ein nicht-trivialer Weg) auf einer MODE Variable. So etwas wie das vereinfachte Beispiel unten.

Zwei schnelle Punkte: Ich weiß, ich könnte nur die Größe arrays nach der größten Größe von MODE benötigt, aber ich möchte nicht, weil (im Gegensatz zum vereinfachten Beispiel unten) manchmal eine Handvoll dieser Dimensionen sind wird extrem groß, während andere winzig sind.

Außerdem möchte ich statisch definierte globale Arrays verwenden - anstatt sie zur Laufzeit dynamisch zuzuordnen. Ich möchte, dass der Compiler die Größen zur Kompilierzeit hat.

//** 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

Makros sind Ersetzungen. – Jack

+0

Ich sehe nicht, was Sie mit einem [S1] meinen. Was versuchst du dort zu machen? –

Antwort

10

Sie müssen zuerst eine Reihe von Hilfsmakros definieren, bevor Sie dies auf einfache Weise tun können:

#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]; 

Es gibt eine Reihe von Preprozessor-Bibliotheken können Sie mit dem Boilerplate-Code (Boost PP, P99) bekommen, oder Sie können einfach Ihre eigenen rollen. Das Hauptproblem besteht darin, dass Sie ARG-Makros basierend auf der größten Anzahl von Argumenten definieren müssen, die Sie jemals bearbeiten möchten.

7

Wahrscheinlich das Beste, was Sie tun können, ist so etwas wie dieses:

#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

Danke Paul - das ist ein bisschen chaotisch, aber könnte das Problem lösen. Ich wusste nicht, dass du das kannst. Ich nehme an, es gibt keine "eleganteren" Möglichkeiten, es zu tun? – user1735592

+0

Nein - der Präprozessor ist wirklich sehr begrenzt und war nicht für diese Art von Missbrauch ausgelegt. Ich bin mir nicht sicher, warum diese Antwort ein anonymes Down-Vote bekommen hat - es ist nicht sehr elegant, aber es löst das Problem. Oh gut ... –

+1

Ich sehe auch keinen Grund, warum es abgelehnt werden sollte. Nochmals vielen Dank für die Idee. – user1735592

3

Ich fürchte, es keine solche Möglichkeit.

Ich schlage vor, den folgenden Ansatz statt:

#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