Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > двумерный массив


Автор: intel 28.10.2009, 21:22
Здравствуйте.
Есть такая функция:
Код

void print(double matrix[MAX_SIZE][MAX_SIZE], int size)
{
    int i;
    for (i = 0; i < size; i++)
    {                
        int j;
        for (j = 0; j < size; j++)
        {               
            printf("%1.0f\t", matrix[i][j]);                
        }
        printf("\n");                
    } 
}

Проблема в том что если я передаю в неё массив размера size, где size меньше MAX_SIZE, то она перестаёт коректно работать, то бишь выдаёт пару значений из массива и много муссора. В этот самый мусор и есть моя проблема - откуда он?!  Подскажите, ребят

Автор: KuMa1104 28.10.2009, 22:35
В с++ не силен.
Но  как я понемаю масив у тебя лежит в памяти и функция читает по указаннаму адресу масив данных размером 8 баит * size.

А так как в памяти после твоего масива идёт какаято другая инфа. то компьётер читает её пока на дойдет до нужного места (начал масива + size)

Автор: jonie 28.10.2009, 22:38
intel, как вызываешь показывай, и откуда буфер берешь с данными тоже

Автор: intel 29.10.2009, 00:53
создаю и заполняю массив:
Код

double matrix[5][5] = { {1,2,3,4,5},
                        {6,7,8,9,10},
                        {11,12,13,14,15},
                        {16,17,18,19,20},
                        {21,22,23,24,25} };


Вот так вызываю:

Код

print(matrix,5);


Всё происходит в мэйне. Пишу на Dev-C++

Автор: Anikmar 29.10.2009, 08:35
Так делать вообще нельзя.

По логике должно выдавать правильно первые n элементов.
Странно, что  это компилируется.

ИМХО Терпеть не могу статические массивы  smile 

Размеры массивов передаваемого и в прототипе функции должны совпадать.

Автор: andrew_121 29.10.2009, 09:07
Цитата(intel @  29.10.2009,  00:53 Найти цитируемый пост)
double matrix[5][5] =

Код

typedef std::vector<std::vector<double> > matrix;
...
void print(const matrix&);
...
matrix m(...);
...
print(m);
...

Автор: zim22 29.10.2009, 09:08
Цитата(intel @  28.10.2009,  20:22 Найти цитируемый пост)
MAX_SIZE

чему равен?

Автор: Cheloveck 29.10.2009, 09:09
http://forum.vingrad.ru/index.php?showtopic=278215&view=findpost&p=2007631

Автор: andrew_121 29.10.2009, 09:24
Цитата(Cheloveck @  29.10.2009,  09:09 Найти цитируемый пост)
Тема только что была 

Вот только я не понял, почему в том коде контейнеров нет?

Автор: jonie 29.10.2009, 09:31
Anikmar, почему это нельзя?
Код

#define MAX_SIZE 5

void print(double matrix[MAX_SIZE][MAX_SIZE], int size)
{
    int i;
    for (i = 0; i < size; i++)
    {                
        int j;
        for (j = 0; j < size; j++)
        {               
            printf("%1.0f\t", matrix[i][j]);                
        }
        printf("\n");                
    } 
}


int main(int argc, char** argv)
{

    double matrix[5][5] = { {1,2,3,4,5},
    {6,7,8,9,10},
    {11,12,13,14,15},
    {16,17,18,19,20},
    {21,22,23,24,25} };

    print(matrix,3);

    return 0;
}




все работает штатно, как и должно быть.
У автора где-то портится память очевидно?

Автор: andrew_121 29.10.2009, 09:38
Цитата(jonie @  29.10.2009,  09:31 Найти цитируемый пост)
почему это нельзя?

А почему не использовать контейнеры?

и:
Цитата(jonie @  29.10.2009,  09:31 Найти цитируемый пост)
double matrix[5][5] =

наверное все же так:
Код

double matrix[MAX_SIZE][MAX_SIZE] =

Автор: Cheloveck 29.10.2009, 10:21
Цитата(andrew_121 @  29.10.2009,  10:24 Найти цитируемый пост)
Вот только я не понял, почему в том коде контейнеров нет? 

Из-за специфики ТС. Думаю его нельзя было озадачивать контейнерами))

Автор: intel 29.10.2009, 20:26
Прошу прощения, Модеры, что поднимаю уже на сто раз разжёванную тему, но к сожалению после долгих хождений по форумам я так ничего и не нашёл.

Спасибо за комментарии и советы, но всётаки вопрос остаётся открытым. Постараюсь описать по подробнее.
В общем дана довольно-таки простенькая задачка: Напишите функцию, которая вычисляет детерминанту матрицы размером  N x N, где N define-константа. Функция имеет следующий прототип: 
Код
double get_det(double matrix[N][N], int size)

Побегал по форумам и пришёл к выводу, что реализовать это дело рекурсивно было бы самым изящным и наглядным способом. 
Значит так; вот что я тут накумекал: 
Создаю матрицу размером N, передаю в функцию get_det(matrix, N), которая создаёт tmp-матрицу размером (size-1)*(size-1), заполняет её значениями из переданной матрицы (без 0. строки и i. столбца) и вызывает саму себя, но уже с tmp-матрицей размером (size-1)x(size-1), size-1 и т.д. пока size > 1. 
Вот тут то и весь геморой, то бишь в прототипе размер матрицы равен N x N, а передаю (N-1) x (N-1) (первый рекурс-вызов)!!

Надеюсь ход мыслей понятен. Объяснил как мог. Господа Прогеры, может у вас есть более простое решение?, а то у меня после явы при виде статических массивов и указателей, волосы дыбом встают. Спасибо

Автор: mes 29.10.2009, 21:01
Цитата(intel @  29.10.2009,  19:26 Найти цитируемый пост)
реализовать это дело рекурсивно...при виде статических массивов и указателей, волосы дыбом встают


вот Вам пример  по рекурсивному заполнению статического массива, может поможет разобраться в вопросе :
Код

#include <iostream>

#define $N 5

int mx[$N][$N] = { 0 };

void mxfn ( int mx[][$N], int size)
{
    if (!size) return;

    for (int i=0; i<size; ++i)
      for (int j=0; j<size; ++j)
        mx[i][j] +=1;

    mxfn (mx, size-1);
}

void mxprint  (int mx[][$N] )
{
     for (int i=0; i<$N; ++i)
     {
       for (int j=0; j<$N; ++j)
         std::cout <<mx[i][j]<< " ";

       std::cout << std::endl;
     }
}


int main(void)
{

     mxfn (mx, $N);
     mxprint (mx);

   return 0;
}


Автор: 17dufa 30.10.2009, 14:29
я подозреваю, что двумерный массив matrix[N][N] при компиляции становится одномерным. как следствие matrix[1][2] на самом деле будет matrix[1*N+2]. так как в вызываемой функции и вызывающей разные значения N получается бардак при адресации (положим в вызывающей N = 5, тогда matrix[1][2] на самом деле matrix[7], а в вызываемой N = 10 и как следствие matrix[1][2] на самом деле становится matrix[12]). не хотите контейнеров - используйте двойной указатель и динамическое выделение памяти.

Автор: mes 30.10.2009, 14:51


Цитата(17dufa @  30.10.2009,  13:29 Найти цитируемый пост)
я подозреваю, что двумерный массив matrix[N][N

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

Цитата(17dufa @  30.10.2009,  13:29 Найти цитируемый пост)
получается бардак

где то я это уже слышал...  smile 

Цитата(17dufa @  30.10.2009,  13:29 Найти цитируемый пост)
так как в вызываемой функции и вызывающей разные значения N 

неа.. смотрите внимательней smile

длина строки ($N)  массива всегда одна и та же, а size определяет лишь сколько элементов  использовать.

Автор: 17dufa 30.10.2009, 15:01
mes, у топикастера - разная:
Цитата(intel @  29.10.2009,  20:26 Найти цитируемый пост)
Вот тут то и весь геморой, то бишь в прототипе размер матрицы равен N x N, а передаю (N-1) x (N-1) (первый рекурс-вызов)!!



Автор: mes 30.10.2009, 15:29
Цитата(17dufa @  30.10.2009,  14:01 Найти цитируемый пост)
у топикастера - разная:

длина матрицы определена в прототипе функции... компилятор не позволит передать другой длины..

Автор: 17dufa 30.10.2009, 15:53
mes, кхем. тогда надо просить intel привести кусок кода. словесное описание недостаточно красноречиво (по крайней мере для меня). ну или советовать переходить на double** и начинать релаксировать от мемори ликов smile

Автор: Anikmar 31.10.2009, 00:13
Цитата(jonie @  29.10.2009,  09:31 Найти цитируемый пост)
Anikmar, почему это нельзя?


Нельзя - потому, что типы данных не совпадают.
Что происходит у автора я понятия не имею - потому, что при описанных условиях это не должно компилироваться (в нормальном режиме - без изуверств, которые С++ позволяет делать).

Можно только при 
Цитата(Anikmar @  29.10.2009,  08:35 Найти цитируемый пост)
Размеры массивов передаваемого и в прототипе функции должны совпадать. 


Что вы в своем примере наглядно и продемонстрировали. - Размерности совпали - все впорядке.

Да и теоритически невозможно - смещение по индексу он (компилятор) физически не сможет правильно посчитать.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)