Array-Format für #define (C-Präprozessor)

Lesezeit: 4 Minuten

Benutzeravatar von user1735592
Benutzer1735592

Wahrscheinlich eine naive Frage – ich habe vor 20 Jahren programmiert und seitdem nicht viel codiert. Meine Erinnerung daran, wie die C preprocessor Werke ist seither stark verkümmert…

Ich schreibe eine sehr einfache C Programm und ich versuche, ein paar statische globale Arrays zu deklarieren, aber die Größe der arrays (auf nicht triviale Weise) abhängig wäre von a MODE Variable. Etwas wie das vereinfachte Beispiel unten.

Zwei schnelle Punkte: Ich weiß, dass ich die Größe einfach könnte arrays entsprechend der größten Größe, die von jedem benötigt wird MODEaber ich möchte das nicht, weil (anders als im vereinfachten Beispiel unten) manchmal eine Handvoll dieser Dimensionen extrem groß sein werden, während andere winzig sind.

Außerdem möchte ich statisch definierte globale Arrays verwenden, anstatt sie zur Laufzeit dynamisch zuzuweisen. 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];

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

    – ich bin so verwirrt

    10. Oktober 2012 um 17:07 Uhr


  • Ich verstehe nicht, was du mit a meinst[S1]. was versuchst du da zu machen?

    – ich bin so verwirrt

    10. Oktober 2012 um 17:10 Uhr

  • Durch eine[S1]ich versuche, ein globales Array ‘a’ mit S1-Elementen zu deklarieren, wobei S1 basierend auf dem Wert von Modus definiert wurde.

    – Benutzer1735592

    10. Oktober 2012 um 17:15 Uhr

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 Präprozessor-Bibliotheken, die Sie mit dem Boilerplate-Code (Boost PP, P99) erhalten können, oder Sie können einfach Ihre eigenen erstellen. Das Hauptproblem besteht darin, dass Sie ARG-Makros basierend auf der größten Anzahl von Argumenten definieren müssen, die Sie jemals verarbeiten möchten.

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

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

  • Danke Paul – das ist ein bisschen chaotisch, könnte aber das Problem lösen. Ich hatte nicht gewusst, dass du das kannst. Ich nehme an, es gibt keine “eleganteren” Möglichkeiten, dies zu tun?

    – Benutzer1735592

    10. Oktober 2012 um 17:21 Uhr


  • Nein – der Präprozessor ist wirklich sehr eingeschränkt und wurde nicht für diese Art von Missbrauch entwickelt. Ich bin mir nicht sicher, warum diese Antwort anonym abgelehnt wurde – es ist nicht sehr elegant, aber es löst das Problem. Nun ja…

    – PaulR

    10. Oktober 2012 um 19:50 Uhr


  • Ich sehe auch keinen Grund, warum er abgelehnt werden sollte. Nochmals vielen Dank für die Idee.

    – Benutzer1735592

    10. Oktober 2012 um 20:13 Uhr

Benutzeravatar von Fayeure
Fayeure

Ich weiß, ich bin etwas zu spät, aber Sie können das auch tun, was viel einfacher ist, ich denke nicht, dass es sehr schnell ist, aber für kleine Programme wird es den Zweck erfüllen

#include <stdio.h>
#define SIZE_LIST (int[]){2, 7, 23, 33, 12, 76}

int main(void)
{
    for (int i = 0; i < 6; i++)
        printf("%d\n", SIZE_LIST[i]);
    return (0);
}

Ich fürchte, eine solche Möglichkeit gibt es nicht.

Ich schlage stattdessen folgende Vorgehensweise vor:

#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

1444160cookie-checkArray-Format für #define (C-Präprozessor)

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy