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


Автор: Xenon 31.5.2006, 22:27
Предположим, есть массив:
Код

const int MAX_STR=20;
const int MAX_SYM=100;
char text[MAX_STR][MAX_SYM];

Есть фунция, допустим, поиска самой длинной строки. Вот ее прототип:
Код

void find_longest (int strcount, char** _text);

Сама функция:
Код

void find_longest (int strcount, char** _text)
{
    int max=0;
    int max_str_num=0;
    for (int i=0;i<strcount;i++)
    {
        int sym=0;
        while (_text[i][sym]!=13) //На это обращение, к примеру, жалуется
        {
            sym++;
        }
        if (sym>max)
        {
            max=sym;
            max_str_num=i;
        }
    }
cout << "Samaja dlinnaja stroka: " << max_str_num;
}

Я вызываю функцию при помощи:
Код

find_longest (str_count,(char**)&text);

Компилятор матюгается но неправильное использование массива в функции ... Как быть?
Сначала задачу выполнял без указателей - просто создавалась копия массива при вызове функции и с нею работалось. А теперь как? Ведь мы передаем указателей и мы не знаем, сколько там элементов в том массиве, на который ссылается указатель, который передается функцие в качестве аргумента.
Как в таких ситуациях быть?

PS. И почему нужно явно указывать типа массива find_longest (str_count,(char**)&text); И почему перед именем массива надо ставить &? Ведь при передаче массива в функцию text уже изначально передается, как ссылка на адресс в памяти ...  

Автор: MAKCim 31.5.2006, 22:39
Цитата

И почему нужно явно указывать типа массива find_longest (str_count,(char**)&text); 

потому что тип text != char**
Цитата

Как быть?

Код

void find_longest (int strcount, char* _text);
...
find_longest (str_count,&text[0][0]);

в памяти text располагается непрерывно и линейно

Добавлено @ 22:43 
Цитата

Код

 while (_text[i][sym]!=13) //На это обращение, к примеру, жалуется


Код

while (_text[i*colums+sym]!=13)   // colums - число столбцов
 

Автор: Xenon 31.5.2006, 23:07
MAKCim 
А нельзя к массиву двумерному обращаться, как к двумерному? Я понимаю, что все равно в памяти все храниться, как одномерный, но все же ... Нельзя никак?

Цитата
потому что тип text != char**

В смысле, почему? Ведь и то и другое типа char ... 

Если что, вот вся задача ... может тут можно чего удобнее сделать.
Код

#include "stdafx.h"
#include "iostream"
#include "conio.h"
using namespace std;
const int MAX_STR=20;
const int MAX_SYM=100;
void check_matrix (int strcount, char** _text);
void display_string (int string, char** _text);
void find_longest (int strcount, char** _text);

int main(int argc, _TCHAR* argv[])
{
    char text[MAX_STR][MAX_SYM];
    int str_count=0;
    for (int str=0;str<MAX_STR;str++) //Cikl vvoda strok
    {
        cout << str << "| ";
        for (int sym=0;sym<MAX_SYM;sym++)
        {
            char ch;
            ch=_getche(); //Vvodim simvol
            text[str][sym]=ch;
            if (ch==13) //Jesli nazhali ENTER, to ....
            {
                break; //Vihodim i ...
            }
        }
        cout << endl;
        str_count++; //... uvelichivajem schetchik strok
        if (text[str][0]==13) //Jesli posledniaja stroka pustaja
        {
            cout << endl;
            break;
        }
    }
    check_matrix(str_count,(char**)&text);
    find_longest (str_count,(char**)&text);
    _getch();
return 0;
}

void check_matrix (int strcount, char** _text) //Proverka na uslovije
{
    for (int str=0;str<strcount;str++)
    {
        for (int sym=0;sym<MAX_SYM;sym++)
        {
            if (_text[str][sym]=='E' || _text[str][sym]=='+' || _text[str][sym]=='-' || (_text[str][sym]>='0' && _text[str][sym]<='9')) //Jesli stroka soderzhit +, ili -, ili E, ili cifru
            {
                display_string(str,_text); //Otobrazhajem stroku i ...
                break; //... vihodim
            }
        }
    }
}

void display_string (int string,char** _text)

{
    cout << string << "| ";
    for (int i=0;i<MAX_SYM;i++)
    {
        if (_text[string][i]==13) //Jesli vstreciajem v stroke priznak nazhatije ENTER
        {
            cout << endl;
            break;
        }
        cout << _text[string][i]; //Vivodim simvol stroki
    }
}

void find_longest (int strcount, char** _text)
{
    int max=0;
    int max_str_num=0;
    for (int i=0;i<strcount;i++)
    {
        int sym=0;
        while (_text[i][sym]!=13)
        {
            sym++;
        }
        if (sym>max)
        {
            max=sym;
            max_str_num=i;
        }
    }
cout << "Samaja dlinnaja stroka: " << max_str_num;
}

 

Автор: likehood 1.6.2006, 09:11
Цитата(XenonSk @  1.6.2006,  00:07 Найти цитируемый пост)
А нельзя к массиву двумерному обращаться, как к двумерному? Я понимаю, что все равно в памяти все храниться, как одномерный, но все же ... Нельзя никак?

Можно, но придется задать вторую размерность массива в прототипе функции:
Код

void find_longest (int strcount, char _text[][MAX_SYM]);

Это связано с тем, что тип двумерного массива не совпадает с char**.
char** m - это массив из указателей, каждый из них указывает на свой одномерный массив.
char m[MAX_STR][MAX_SYM] - по-сути одномерный массив.
Операция m[i][j] работает по-разному для двух типов массивов, поэтому и возникает путаница.
 

Автор: Xenon 1.6.2006, 11:51
baronp  Ну я так и дела изначально, но в таком случае создается копия объекта ... А если массив большой? Не копировать же ... 

Автор: likehood 1.6.2006, 12:24
Цитата(XenonSk @  1.6.2006,  12:51 Найти цитируемый пост)
 но в таком случае создается копия объекта

кто сказал? массивы всегда передаются по указателю 

Автор: Xenon 1.6.2006, 13:27
Ну я просто привык, что, раз если объекты при передаче в функцию копируются, то и массивы тоже .. Так, значит, не нужно замарачиваться с указателями, если хочется экономить память ... если массив не копируется. Я только из соображений экономии хотел заюзать указатели smile 

Автор: likehood 1.6.2006, 13:30
Цитата(XenonSk @  1.6.2006,  14:27 Найти цитируемый пост)
 Так, значит, не нужно замарачиваться с указателями, если хочется экономить память

ага 

Автор: Xenon 1.6.2006, 13:35
Понял, спасибо, а я чего-то зациклился smile Спасибо ... бывает 

Автор: likehood 1.6.2006, 13:58
...бываетsmile 

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