Консультация № 75887
15.02.2007, 17:08
0.00 руб.
0 5 5
Здравствуйте дорогие эксперты. Я хотел бы спросить как в языке С одномерный массив преобразовать в многомерный? Заранее спасибо за ответы.

Обсуждение

Неизвестный
15.02.2007, 17:31
общий
это ответ
Здравствуйте, GOrilla!
Изменить сам тип? Никак.
Одномерный массив выглядит, например как
int * pArray;
или
int arr [size];
Двумерный:
int ** ppArray;
или
int arr [size][size];

Вы не сможете изменить тип int* на int**.
Если же имеется в виду просто преобразование, то как обычно:

void func (int * pArr)
{
int ** ppArr;
ppArr = (int **)pArr;
или
ppArr = (int **)&pArr;
}

вы должны сами выбирать, в зависимости от того, что на самом деле находится в pArr. Но если он создавался как одномерный массив, то в результате
ppArr = (int **)pArr;
вы получите фиг знает что, а в результате
ppArr = (int **)&pArr;
вы получите адрес массива
переделать же его в двумерный просто так вот не получится
Неизвестный
15.02.2007, 19:23
общий
это ответ
Здравствуйте, GOrilla!
Не буду утверждать, но помоему никак.
создаете новый многомерный массив и переносите туда нужным образом данные.
Если массив изначально задан как одномерный под него и память будет выделена соответствующе.
в определенных случаях от переписывания массива вас могут спасти указатели. То есть ваш массив останется одномерным, но данные из него вы будете по другому.
например был int a[10]; а вы хотите чтоб стал int b[2][5]; (одну строку разрезать пополам)то наш псевдо массив b это указатель на a смещенный на j*5+i элементов.
Во всех других случаях переписывайте массив в другой
Неизвестный
15.02.2007, 19:44
общий
это ответ
Здравствуйте, GOrilla!

данные в одномерном массиве и многомерном хранятся одинаково, тоесть последовательно в памяти.
все зависит от интерпритации одномерного массива.

самый простой и очевидный способ это просто скопировать содержимое одномерного массива в многомерный. в приложении пример 1
но в данном случае вы дублируете массив.

можно просто вспомнить что синтаксис доступа к многомерному массиву это всего лишь удобная запись, но никто не мешает воспользоватся и указателями.
тоесть A[i][j] в вашем случае аналог *(M + 5*i + j)
смотрите пример 2 в приложении.
недостаток метода - некрасивый синтаксис
преимущество - не происходит никакого копирования

Приложение:
пример 1:#include <stdio.h>#include <string.h>int main(){ int i, j; char M[15] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; char A[3][5]; memcpy(A, M, sizeof(A)); for (i = 0; i < 3;i++) { for (j = 0; j < 5; j++) printf("%02d ", A[i][j]); printf("\n"); } return 0;}пример 2#include <stdio.h>int main(){ int i, j; char M[15] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; printf("\n"); for (i = 0; i < 3;i++) { for (j = 0; j < 5; j++) printf("%02d ", *(M + 5*i + j)); printf("\n"); } return 0;}
Неизвестный
16.02.2007, 00:04
общий
это ответ
Здравствуйте, GOrilla!

Для удобства и наглядности извлечения данных из одномерного массива можно использовать макрос(если массив часто используется и заранее известно его имя).
Допустим имеется массив matrix[16], который нужно интерпретировать как матрицу 4*4:

#define m(i,j) *(matrix + j*4+i) //либо matrix[i+j*4]

float matrix[16];

int main()
{
m(0,0) = 1;
m(0,1) = 2;
m(0,3) = m(0,0) + m(0,1);
}
Неизвестный
16.02.2007, 00:35
общий
это ответ
Здравствуйте, GOrilla!
Мона примерно так (см. приложение):


Приложение:
char a[0x100];char (*b)[0x10][0x10];//b - указатель на массив (0x10 X 0x10)b=((char (*)[0x10][0x10])&a);for(int i=0;i<0x10;i++)for(int j=0;j<0x10;j++) (*b)[i][j]=i*0x10+j;
Форма ответа