Конечно. Просто напишите свою собственную библиотеку, чтобы справиться с этим:
#include <stdio.h>
#include <limits.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdarg.h>
#include <assert.h>
struct arrnd_s {
void *memory;
size_t membsize;
size_t *dims;
size_t dimcnt;
};
static inline size_t _arrnd_arraysize(struct arrnd_s *t)
{
size_t ret = 1;
for (size_t i = 0; i < t->dimcnt; ++i) {
ret *= t->dims[i];
}
return ret;
}
struct arrnd_s *arrnd_new(size_t membsize, size_t dimcnt, ...)
{
struct arrnd_s *t = malloc(sizeof(*t));
if (t == NULL) {
goto T_MALLOC_ERR;
}
t->dims = malloc(dimcnt * sizeof(*t->dims));
if (t->dims == NULL) {
goto T_DIMS_ERR;
}
va_list va;
va_start(va, dimcnt);
for (size_t i = 0; i < dimcnt; ++i) {
t->dims[i] = va_arg(va, size_t);
}
va_end(va);
t->dimcnt = dimcnt;
t->memory = malloc(_arrnd_arraysize(t) * membsize);
if (t->memory == NULL) {
goto T_MEMORY_ERR;
}
t->membsize = membsize;
return t;
T_MEMORY_ERR:
free(t->dims);
T_DIMS_ERR:
free(t);
T_MALLOC_ERR:
return NULL;
}
void arrnd_free(const struct arrnd_s *t)
{
assert(t != NULL);
free(t->memory);
free(t->dims);
free((void*)t);
}
size_t arrnd_arraysize(struct arrnd_s *t)
{
assert(t != NULL);
assert(t->dims != NULL);
assert(t->dimcnt >= 1);
return _arrnd_arraysize(t);
}
size_t arrnd_getdim(struct arrnd_s *t, size_t dimpos)
{
assert(t != NULL);
assert(t->dims != NULL);
assert(t->dimcnt >= 1);
assert(dimpos < t->dimcnt);
return t->dims[dimpos];
}
void *arrnd_getpnt_v(struct arrnd_s *t, va_list va)
{
assert(t != NULL);
assert(t->dims != NULL);
assert(t->dimcnt >= 1);
size_t pos = 0;
for (size_t i = 0; i < t->dimcnt; ++i) {
const size_t dim = va_arg(va, size_t);
pos += dim;
if (i != t->dimcnt - 1) {
pos *= t->dims[i];
}
}
return &((char*)t->memory)[pos * t->membsize];
}
void *arrnd_getpnt(struct arrnd_s *t, ...)
{
va_list va;
va_start(va, t);
void * const ret = arrnd_getpnt_v(t, va);
va_end(va);
return ret;
}
int main()
{
struct arrnd_s *arrnd = arrnd_new(sizeof(int), 4, 2, 4, 4, 8);
assert(arrnd != NULL);
assert(arrnd_arraysize(arrnd) == 2 * 4 * 4 * 8);
for (size_t i = 0; i < arrnd_getdim(arrnd, 0); ++i) {
for (size_t j = 0; j < arrnd_getdim(arrnd, 1); ++j) {
for (size_t k = 0; k < arrnd_getdim(arrnd, 2); ++k) {
for (size_t l = 0; l < arrnd_getdim(arrnd, 3); ++l) {
*(int*)arrnd_getpnt(arrnd, i, j, k, l) = i + j + k + l;
}
}
}
}
for (size_t i = 0; i < arrnd_getdim(arrnd, 0); ++i) {
for (size_t j = 0; j < arrnd_getdim(arrnd, 1); ++j) {
for (size_t k = 0; k < arrnd_getdim(arrnd, 2); ++k) {
for (size_t l = 0; l < arrnd_getdim(arrnd, 3); ++l) {
printf("[%zu][%zu][%zu][%zu] = %d\n", i, j, k, l, *(int*)arrnd_getpnt(arrnd, i, j, k, l));
}
}
}
}
arrnd_free(arrnd);
return 0;
}
Как примечание: в C я всегда считал это классным, но это время компиляции, а не времени выполнения:
int main() {
int memory[256];
for (size_t i = 0; i < sizeof(memory)/sizeof(*memory); ++i) {
memory[i] = i;
}
int *arr1d = (void*)memory;
printf("1d[%d] = %d == %d\n", 1, arr1d[1], memory[1]);
int (*arr2d)[16] = (void*)memory;
printf("2d[%d][%d] = %d == %d\n", 2, 2, arr2d[2][2], memory[2 * 16 + 2]);
int (*arr3d)[8][8] = (void*)memory;
printf("3d[%d][%d][%d] = %d == %d\n", 2, 2, 2, arr3d[2][2][2], memory[(2 * 8 + 2) * 8 + 2]);
int (*arr4d)[4][4][4] = (void*)memory;
printf("4d[%d][%d][%d][%d] = %d == %d\n", 2, 2, 2, 2, arr4d[2][2][2][2], memory[((2 * 4 + 2) * 4 + 2) * 4 + 2]);
int (*arr5d)[2][2][2][2] = (void*)memory;
printf("5d[%d][%d][%d][%d][%d] = %d == %d\n", 1, 1, 1, 1, 1, arr5d[1][1][1][1][1], memory[(((1 * 2 + 1) * 2 + 1) * 2 + 1) * 2 + 1]);
return 0;
}