2011-01-17 1 views
0

Как я могу сделать следующее?Jagged Array in C (3D)

double layer1[][3] = { 
    {0.1,0.1,0.8}, 
    {0.1,0.1,0.8}, 
    {0.1,0.1,0.8}, 
    {0.1,0.1,0.8} 
}; 
double layer2[][5] = { 
    {0.1,0.1,0.1,0.1,0.8} 
}; 
double *upper[] = {layer1, layer2}; 

Я прочел следующее, пробовав разные идеи; но безрезультатно. Do jagged arrays exist in C/C++?

я понимаю (я надеюсь), что

double **upper[] = {layer1, layer2}; 

подобно тому, что я хотел бы, но не будет работать, потому что слои не являются массивы указателей. Я использую C намеренно.


Я пытаюсь воздержаться от этого (что работает).

double l10[] = {0.1,0.1,0.8}; 
//l11 etc 
double *l1[] = {l10,l11,l12,l13}; 
double l20[] = {0.1,0.1,0.1,0.1,0.8}; 
double *l2[] = {l20}; 

double **both[] = {l1, l2}; 
+0

Вы утверждаете, что это C, но вы используете 'cout'. – chrisaycock

+0

Причина привычки, нерелевантная - исправлена ​​ – dcousens

ответ

3

В современном C есть инструмент вызов соединения буквальное достичь, по крайней мере частично, что вы, кажется, хотят:

double (*(layer1[])) = { 
    (double[]){0.1,0.1,0.8}, 
    (double[]){0.1,0.1,0.8}, 
    (double[]){0.1,0.1,0.8}, 
    (double[]){0.1,0.1,0.8} 
}; 
double (*(layer2[])) = { 
    (double[]){0.1,0.1,0.1,0.1,0.8} 
}; 
double (*(*(upper[]))) = {layer1, layer2}; 

Я положил в () типов, чтобы показать вам правило привязки для типы. Но будьте осторожны, что при таком типе программирования вам всегда нужно запоминать границы массива самостоятельно.

Edit: Конструкция, как (double[]){ 0.0 } называется соединение буквальным и как тот же эффект, что и ваши временные массивы, которые вы объявивших в вашей второй версии. Преимущество состоит в том, что вам не нужно изобретать для них соглашение об именах и что единственный способ получить доступ к этим временным переменным - это через большой массив. Может быть, лучше было бы поставить в const во все это, чтобы вы случайно не изменить указатели:

double (*const(layer1[])) = { 
    (double[]){0.1,0.1,0.8}, 
    (double[]){0.1,0.1,0.8}, 
    (double[]){0.1,0.1,0.8}, 
    (double[]){0.1,0.1,0.8} 
}; 
double (*const(layer2[])) = { 
    (double[]){0.1,0.1,0.1,0.1,0.8} 
}; 
double (*const(*const(upper[]))) = {layer1, layer2}; 

Это все еще позволяет изменять содержимое (все doubles), но не указатели. Если вы знаете, что сами doubles не меняются во время всей программы, измените double на double const всюду.

+0

Спасибо за ответ, это для очень специфического приложения, и оценки всегда известны при компиляции и хранятся в константах. Могу ли я спросить, как (double []) действительно повлияло на обработку массива? – dcousens

+1

@ Даниэль: напр. 'layer1' больше не относится к типу' double [] [3] ', теперь он имеет тип' double * [] '. т. е. это массив указателей на «double». Например, 'sizeof' будет работать по-другому. –

0

Layer1 и Layer2 - это массивы указателей, по самому определению зубчатых массивов. Там нет оснований для

double ** upper[] = {layer1, layer2} 

Не работать. Если это не так, отправьте сообщение об ошибке.

Единственная проблема заключается в том, что ваши массивы распадаются на указатели. Если это проблема для вас, вам нужно использовать C99 и прочитать this post в уже упомянутой теме.

+0

Нет, они не являются, массивы layer1, layer2 являются очень определенными массивами массивов. (Ошибка показана ниже, благодаря ephemient) – dcousens

+0

Не работает. 'layer1' имеет тип' double [4] [3] '(который распадается на' double * [3] ', а не' double ** ') и аналогично для' layer2'. – ephemient

+0

В C есть небольшая явная разница между массивом и указателем (есть различия, но это должно объяснить их здесь) Но я должен сказать, что я сам его не тестировал, время для запуска старого компилятора lill :) – dtech

1
struct { 
    size_t length; 
    size_t stride; 
    double *data; 
} upper = { 
    { 
    sizeof(layer1)/sizeof(layer1[0]), 
    sizeof(layer1[0])/sizeof(layer1[0][0]), 
    (double *)layer1, 
    }, 
    { 
    sizeof(layer2)/sizeof(layer2[0]), 
    sizeof(layer2[0])/sizeof(layer2[0][0]), 
    (double *)layer2, 
    }, 
}; 

int i, j, k; 
for (i = 0; i < sizeof(upper)/sizeof(upper[0]); i++) { 
    for (j = 0; j < upper[i].length; j++) { 
    for (k = 0; i < upper[i].stride; k++) 
     printf(" %d" + !k, upper[i].data[upper[i].stride * j + k]); 
    printf("\n"); 
    } 
    printf("\n"); 
} 

Вы должны понимать, что многомерные массивы в C являются просто крупными рядами, упакованными в линейную часть хранилища. Фактические размеры известны только типам во время компиляции: их нигде не найти в данных во время выполнения.