2012-10-10 52 views
10

Probablemente una pregunta ingenua: solía programar hace 20 años y no he codificado mucho desde entonces. Mi memoria de cómo las obras C preprocessor ha atrofiado significativamente desde entonces ...Formato de matriz para #define (preprocesador C)

Estoy escribiendo un programa muy simple C y yo estoy tratando de declarar un par de matrices globales estáticos, pero el tamaño de la arrays sería dependiente (en una forma no trivial) en una variable MODE. Algo así como el ejemplo simplificado a continuación.

Dos puntos rápidos: Sé que sólo podía dimensionar el arrays acuerdo con el tamaño más grande que necesita cualquier MODE, pero no quieren que debido a que (al contrario que en el ejemplo simplificado abajo) a veces un puñado de estas dimensiones son va a ser extremadamente grande, mientras que otros son muy pequeños.

Además, deseo utilizar matrices globales definidas estáticamente, en lugar de asignarlas dinámicamente en el tiempo de ejecución. Quiero que el compilador tenga los tamaños en tiempo de compilación.

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

Las macros son sustituciones. – Jack

+0

No veo a qué te refieres con un [S1]. ¿Qué estás tratando de hacer allí? –

Respuesta

10

Es necesario definir un grupo de macros de ayuda antes de poder hacer esto de una manera sencilla:

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

Hay un montón de "librerías" de preprocesador que puede obtener con el código repetitivo (impulsar PP, P99), o simplemente puede hacer las suyas propias. El principal problema es que necesita definir macros ARG según la mayor cantidad de argumentos que quiera manejar.

7

Probablemente lo mejor que puede hacer es algo como esto:

#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

Gracias Paul: es un poco complicado, pero podría resolver el problema. No sabía que pudieras hacer eso. Supongo que no hay formas 'más elegantes' de hacerlo? – user1735592

+0

No, el preprocesador es realmente muy limitado y no fue diseñado para este tipo de abuso. No estoy seguro de por qué esta respuesta obtuvo un voto negativo anónimo, no es muy elegante pero resuelve el problema. Oh, bueno ... –

+1

Tampoco veo ninguna razón por la que deba ser votado. Gracias de nuevo por la idea. – user1735592

3

Me temo que no hay tal posibilidad.

que sugieren el siguiente enfoque en su lugar:

#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 
Cuestiones relacionadas