una tridimensionales suma multidimensionales matriz matrices llenar imprimir ejemplos como caracteres bidimensionales arreglos c multidimensional-array opencl

tridimensionales - matriz de caracteres en c



macro para simular acceso matriz bidimensional en C (3)

OpenCL solo ofrece acceso a matrices unidimensionales utilizando las especificaciones C99. Sin embargo, mi problema está en dos dimensiones y estoy usando matrices bidimensionales en el lado del host

En lugar de hacer que mi código sea menos legible mediante el cálculo de índices, me gustaría usar una macro C para obtener el elemento A[i][j] . Desafortunadamente soy bastante malo en esto y tengo poca experiencia en C. Creo que tengo la idea general de cómo se hace, pero si alguien pudiera criticarlo sería apreciado.

Sería algo así como:

#define 2d_access(u, y, x) (u[y][x])

donde u es la matriz, y es la fila, y x es la columna y la macro devolverá el valor en u[y][x]

La matriz se asigna estáticamente, por lo que la macro tendría un componente ANCHO.

#define 2d_access(u, y, x) (u[y * WIDTH] + x])


Dado que todas las respuestas hasta ahora se basan en un ancho constante, aquí hay una solución (pesada) para columnas de ancho arbitrario:

#define matrix_type(t) struct { size_t width; t array[]; } #define matrix_alloc(t, w, h) malloc(offsetof(matrix_type(t), array[(w) * (h)])) #define matrix_init(m, t, w, h) / matrix_type(t) *m = matrix_alloc(t, w, h); / if(!m) matrix_alloc_error(); else m->width = (w); #define matrix_index(m, w, h) m->array[m->width * (w) + (h)] // redefine if you want to handle malloc errors #define matrix_alloc_error()

Solo desasigne la matriz con free .

Por supuesto, también puede agregar un campo para la altura y verificar los límites, entre otras cosas. Incluso podría escribirlos como funciones reales, o usar una macro para declarar automáticamente los tipos de struct para que no tenga que usar un tipo de struct anónima para todo. Si lo necesita en la pila, puede usar alloca a costa de la portabilidad.

Si tiene un tamaño de matriz constante, puede utilizar algunos hacks de conversión para lograr una indexación 2D "nativa" (a través del operador [] ):

#define CAT_(x, y) x##y #define CAT(x, y) CAT_(x, y) #define MANGLE(x) CAT(x, _hidden_do_not_use_0xdeadbeef_) #define matrix_init(m, t, w, h) / t MANGLE(m)[(w) * (h)]; / t (*m)[(w)] = (void *)MANGLE(m); // because of the funky typing, `m[0][1]` does what you''d expect it to.

Tenga en cuenta que, a diferencia de la otra solución, esto crea una segunda variable, que probablemente no es muy clara, pero creo que utilicé un método de manipulación bastante claro para que no se interponga en la práctica.


Incluso más limpio sería definir una macro para cada matriz que está utilizando, por lo que puede hacer que se vea exactamente como un acceso de matriz 2D. Entonces, dado el conjunto A , definirías:

#define A(r, c) (A[(r)*WIDTH + (c)])

Tenga en cuenta los paréntesis alrededor de los valores sustituidos. Esto maneja casos donde la sustitución es una expresión, como A(i + 1, j) . Sin los paréntesis, esto se expandiría a A[i + 1*WIDTH + j] , que no es lo que desea:

A[i + 1*WIDTH + j] = A[WIDTH + i + j] != A[(i + 1)*WIDTH + j]

Para evitar el mismo problema con el segundo argumento, ambos se incluyen entre paréntesis en el texto de sustitución.


Sin críticas, ya dio la solución:

#define access_2d(u, y, x) (u[(y) * WIDTH + (x)])

OK, tal vez pienso de manera diferente, pero lo definiría como

// x before y #define access_2d(u, x, y) (u[(y) * WIDTH + (x)])

Eso no es mejor, sin embargo, solo una preferencia.