Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Передача массивов в функции и процедуры, двумерные массивы 
V
    Опции темы
Xenon
Дата 22.12.2006, 16:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1529
Регистрация: 12.4.2006

Репутация: 11
Всего: 50



Anikmar,  следует не забывать, что b - const int* 

Это сообщение отредактировал(а) Xenon - 22.12.2006, 16:43


--------------------
user posted image  
PM MAIL   Вверх
Anikmar
Дата 22.12.2006, 16:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

Репутация: 9
Всего: 59



Цитата

ф-ция в С не может возращать ф-ции или массивы....указатели на них может (ANSI ISO\IEC 14882-2003(E) вроде гдето там есть имеенно такое определение.... )... 


Естественно не может, но если попробовать так:
Код

struct a
{
  char b[100];
}

MyFun(a); - Структура передается по значению вместе с массивом;



Цитата(Xenon @  22.12.2006,  16:43 Найти цитируемый пост)
Anikmar,  следует не забывать, что b - const int*

Спору нет - естественно.


Цитата(JackYF @  22.12.2006,  16:14 Найти цитируемый пост)
Таки нет.

Эта штука создаст массив в стеке из 6 элементов. Никаких указателей на указатели.

Другое дело, что локально a[i][j] будет обрабатываться компилером нормально, но по-другому:
Что-то типа:

*(a + i*n + j);


В статическом варианте при попытке сделать так:
char **a;
char b[3][2];

a = b;

Компилятор выдаст ошибку о преобразовании типов и напишет примерно следующее
"Не могу преобразовать char*[2] в char**

У меня именно так выдал - из этого я сделал вывод, что статическое объявление компилятор также считает массивом указателей.


PM MAIL ICQ   Вверх
KelTron
Дата 22.12.2006, 17:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 745
Регистрация: 8.10.2006
Где: Красноярск

Репутация: нет
Всего: 38



Цитата(Anikmar @  22.12.2006,  15:22 Найти цитируемый пост)

Пу сути дела - имя массива с точки зрения типа С++ является указателем на тип массива.

Если точнее то имя массива - указатель на его первый элемент
Цитата(Anikmar @  22.12.2006,  15:22 Найти цитируемый пост)

int a[2][3] является по сути указателем на массив указателей т.е. int*[2];

Скорее массивом указателей int *a[2], а указателем на массив указателей является a
(int** a)



--------------------
Тысячами незримых нитей обвивает тебя Закон. Разрубишь одну - преступник. Десять - смертник. Все - Бог.
Эвенгар Салладорский, основатель Школы Тьмы.
PM MAIL   Вверх
JackYF
Дата 22.12.2006, 17:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(Anikmar @  22.12.2006,  16:55 Найти цитируемый пост)
У меня именно так выдал - из этого я сделал вывод, что статическое объявление компилятор также считает массивом указателей.


У всех так выдает. Но это ситуации не меняет.

Читаем Страуструпа и Стандарт.

Компилер в этом случае трактует получившееся как массив указателей.
Но указателя на указатели там нет.



--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Anikmar
Дата 22.12.2006, 17:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

Репутация: 9
Всего: 59



Цитата(JackYF @  22.12.2006,  17:09 Найти цитируемый пост)
Компилер в этом случае трактует получившееся как массив указателей.
Но указателя на указатели там нет.


Это уже к семантике русского языка.
Массив указателей или указатель на указатели...

В общем вы поняли  smile 


Цитата(KelTron @  22.12.2006,  17:06 Найти цитируемый пост)
Если точнее то имя массива - указатель на его первый элемент

Я имел в ввиду типы переменных.

объявление 
int a[5];

С точки зрения С++ типом переменной a является "Указатель на int"
А вот значение этого указателя указывает на первый элемент массива.
PM MAIL ICQ   Вверх
KelTron
Дата 22.12.2006, 17:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 745
Регистрация: 8.10.2006
Где: Красноярск

Репутация: нет
Всего: 38



Anikmar, так тоже верно  smile 


--------------------
Тысячами незримых нитей обвивает тебя Закон. Разрубишь одну - преступник. Десять - смертник. Все - Бог.
Эвенгар Салладорский, основатель Школы Тьмы.
PM MAIL   Вверх
JackYF
Дата 22.12.2006, 17:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(Anikmar @  22.12.2006,  17:20 Найти цитируемый пост)
Это уже к семантике русского языка.
Массив указателей или указатель на указатели...


Нет, не к семантике русского языка.

Цитата(Anikmar @  22.12.2006,  17:20 Найти цитируемый пост)
С точки зрения С++ типом переменной a является "Указатель на int"

Нет, не является. Читаем, опять-таки, Страуструпа.
a - не переменная даже, так как она не имеет типа.

При объявлении массива char a[3][2];
в памяти не выделяется ни байта ни под один указатель.


Это сообщение отредактировал(а) JackYF - 22.12.2006, 17:44


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
lasalexx
Дата 21.2.2007, 23:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 192
Регистрация: 19.7.2004
Где: Tbilisi

Репутация: нет
Всего: 1



вот уже несколько дней думаю как можно передать статистический масив функции. в конце концов сделал вот так:

Код

#include <stdio.h>
#include <conio.h>

void show(int (*a)[], int m, int n)
{
int i,j,x;
for (i=0; i<m; i++){
   for (j=0; j<n; j++){
      x=*(*(a+i)+j);
      printf ("%d ",x);
    }
   printf ("\n");
    }
}

main ()
{
int a[3][4]={{4,6,8,10}, {14,16,18,20}, {24,26,28,30}};

show(a,3,4);
getche();
}


но выдает ошибку:
Цитата

Size of the type 'int[]' is unknown or zero


а ведь когда делаю с одномерным масивом
Код

void show (int a[], int n);

всё нормально получается.
Так в чём разница?
И можно ли вообще сделать то что я хочу не используя динамическую память?
PM MAIL WWW ICQ MSN   Вверх
Daevaorn
Дата 22.2.2007, 00:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



Код

#include <stdio.h>
#include <conio.h>


typedef int MyArray[3][4];

void show(MyArray& a, int m, int n)
{
    int i,j,x;
    for (i=0; i<m; i++){
        for (j=0; j<n; j++){
            x=*(*(a+i)+j);
            printf ("%d ",x);
        }
        printf ("\n");
    }
}

int main ()
{
    
    MyArray a = { {4,6,8,10}, {14,16,18,20}, {24,26,28,30}};

    show(a,3,4);
    getche();
    return 0;
}


PM MAIL WWW   Вверх
lasalexx
Дата 22.2.2007, 09:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 192
Регистрация: 19.7.2004
Где: Tbilisi

Репутация: нет
Всего: 1



Цитата(Daevaorn @ 22.2.2007,  00:49)
Код

#include <stdio.h>
#include <conio.h>


typedef int MyArray[3][4];

void show(MyArray& a, int m, int n)
{
    int i,j,x;
    for (i=0; i<m; i++){
        for (j=0; j<n; j++){
            x=*(*(a+i)+j);
            printf ("%d ",x);
        }
        printf ("\n");
    }
}

int main ()
{
    
    MyArray a = { {4,6,8,10}, {14,16,18,20}, {24,26,28,30}};

    show(a,3,4);
    getche();
    return 0;
}


Но тут MyArray матрица 3х4, а я хочу что б функция работала на все размеры.
PM MAIL WWW ICQ MSN   Вверх
vinter
Дата 23.2.2007, 16:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



JusTalionis, тогда используй двойной указатель(**) и динамическое выделение памяти


--------------------
Мой блог
PM MAIL WWW   Вверх
threef
Дата 23.2.2007, 17:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 375
Регистрация: 27.10.2005
Где: Запорожье

Репутация: 9
Всего: 10



Нет необходимости использовать динамическое выделение памяти. А вот внутри функции придется "попотеть" - две квадратных скобки работать откажутся. 
Код


void f(float **p,int x1,int x2)
{
    //float r=p[1][2];// runtime
    float q=*((float*)p + 1*x2+2);//ok 
    cout<<q<<'\n';
}
main()
{
    float x[3][4]={{1,2,3,4},{11,12,13,14},{21,22,23,24}};
    f((float**)x,3,4);

    float y[5][6]={{11,12,13,14},{1,2,3,4},{21,22,23,24}};
    f((float**)y,5,6);

}



Добавлено @ 17:25 
или проще :


Код


#include <iostream.h>
void f(double *p,int x1,int x2)
{
    //double r=p[1][2];// runtime
    double q=*(p + 1*x2+2);//ok 
    cout<<q<<'\n';
}
main()
{
    double x[3][4]={{1,2,3,4},{11,12,13,14},{21,22,23,24}};
    f((double*)x,3,4);

    double y[5][6]={{11,12,13,14},{1,2,3,4},{21,22,23,24}};
    f((double*)y,5,6);

}


Это сообщение отредактировал(а) threef - 23.2.2007, 17:23
PM MAIL   Вверх
Daevaorn
Дата 23.2.2007, 17:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



Цитата(lasalexx @  22.2.2007,  10:49 Найти цитируемый пост)
Но тут MyArray матрица 3х4, а я хочу что б функция работала на все размеры. 

Ну если С-style не принципиален, то:
Код

#include <stdio.h>
#include <conio.h>

template< typename ArrayT >
void show(ArrayT& a, int m, int n)
{
    int i,j,x;
    for (i=0; i<m; i++){
        for (j=0; j<n; j++){
            x=*(*(a+i)+j);
            printf ("%d ",x);
        }
        printf ("\n");
    }
}

int main ()
{
    
    int a[][] = { {4,6,8,10}, {14,16,18,20}, {24,26,28,30}};

    show(a,3,4);
    getche();
    return 0;
}


Это сообщение отредактировал(а) Daevaorn - 23.2.2007, 17:31
PM MAIL WWW   Вверх
vinter
Дата 23.2.2007, 17:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



]threef, это извращения, зачем так издеваться над своим (и чужим мозгом), когда проще выделить память динамически..


--------------------
Мой блог
PM MAIL WWW   Вверх
threef
Дата 23.2.2007, 17:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 375
Регистрация: 27.10.2005
Где: Запорожье

Репутация: 9
Всего: 10



vinter,  извращения - это то, к чему ты не привык ? Так и пиши, "мне это не нравится". Остальное - тема для обсуждения, а не "извращения". Посчитай обращения к менеджеру кучи при динамическом выделении памяти так, как это предлагаешь ты. А не хочешь издеваться над мозгом - пользуй готовые коллекции.
PM MAIL   Вверх
Страницы: (3) Все 1 [2] 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0589 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.