Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
jake09
0 / 0 / 0
Регистрация: 20.11.2014
Сообщений: 20
#1

Работа с двухмерным динамеческим массивом через указатель - C++

20.11.2014, 23:07. Просмотров 939. Ответов 22
Метки нет (Все метки)

Натупил здесь наверное сильно, подскажите ребят, а то долго уже сиджу над этим... Где ошибки? Программу компилирует, но потом выбивает.

C
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
26
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <math.h>
 int main()
 {
    srand(time(NULL));
    const int size_x = 4, size_y = 5, m = 20;
    int **matrix, i, j, d, n[4] = {1,2,3,4}, s;
    matrix = malloc(m*sizeof(int**));
    for (i = 0; i < size_x; i++)
    {
        for (j = 0; j < size_y; j++)
        {
            matrix[i][j] = (rand() % 20)-10;
            d = fabs(matrix[i][j]);
            if((j+1)==d)
            {
                   s++;
            }
        }
        printf("For line %d number of elements that matched is = %d\n", n[i],s);
        free(matrix);
    }
    return 0;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.11.2014, 23:07
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Работа с двухмерным динамеческим массивом через указатель (C++):

Работа с массивом структур в функции через указатель на этот массив - C++
Добрый вечер. Имеется следующая задача: &quot;Разработайте программу, сохраняющую записи (порядковый номер ввода, число с плавающей точкой и...

Развлечения с массивом через указатель - C++
Инициализация указателей. Объявите массив, состоящий из 8 элементов типа short int. Объявите указатель на этот массив и присвойте ему...

Управление двухмерным массивом из функции - C++
Доброго времени суток, пожалуйста, подскажите, как правильно передать в функцию указатель на двухмерный массив, а затем из функции изменять...

В С++ может ли argv быть двухмерным массивом? - C++
int main(int argc, char *argv) { argv = tolower(argv); argv = tolower(argv); Вот что это означает? Когда у argv с двумя...

Работа с массивом с через strcpy_s() - C++
Функция addBrackets принимает массив и преобразует его заключая в скобки . т.е. на на вход массив: text после преобразования: ...

Работа с массивом через геттер и сеттер - C++
#include &lt;iostream&gt; using namespace std; class My_Class { private: int *p; public: My_Class() { p = new int ;

22
Fasterbru
5 / 5 / 2
Регистрация: 18.11.2014
Сообщений: 81
20.11.2014, 23:14 #2
объявляй счетчики так for(int i = 0; i<n;i++)...
и выделение памяти для двумерного массива как-то так:
C++
1
2
3
4
5
6
7
    int n1,n2;
    cin >> n1 >> n2;
    int** a = (int**)malloc(n1*sizeof(int*));
    for (int i = 0; i < n2; i++)
    {
        a[i] = (int*)malloc(n2*sizeof(int));
    }
0
true_bugmaker
28 / 5 / 1
Регистрация: 18.11.2014
Сообщений: 68
20.11.2014, 23:19 #3
двумерный динамический массив размерностью (size_x, size_y) следует выделять так, потому что по факту в сях нету двумерных массивов, создаётся одномерный массив из int*, указателей на одномерные массивы int:
C++
1
2
3
4
matrix = malloc(size_x*sizeof(int*));
for (i = 0; i < size_x; i++) {
      matrix [i] = malloc (size_y * sizeof (int));
}
0
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
3909 / 2146 / 549
Регистрация: 18.10.2014
Сообщений: 3,755
20.11.2014, 23:29 #4
Цитата Сообщение от true_bugmaker Посмотреть сообщение
потому что по факту в сях нету двумерных массивов, создаётся одномерный массив из int*, указателей на одномерные массивы int:
Как можно выделять двумерные динамические массивы (если оба размера являются неконстантными) я рассказывал здесь: Передача двумерного массива в функцию. Ошибка "invalid types for array subscript". Способов как минимум три.

Но если говорить о "сях", то в С поддерживаются и обыкновенные локальные массивы с неконстантной размерностью

C
1
int matrix[size_x][size_y];
поэтому фраза "по факту в сях нету двумерных массивов" мне не совсем ясна.

Добавлено через 5 минут
Цитата Сообщение от jake09 Посмотреть сообщение
C++
1
matrix = malloc(m*sizeof(int**));
Как вы умудрились это скомпилировать??? Функция 'malloc' возвращает 'void *', который неприводим к 'int **' без явного каста. Код не компилируется.

Но в любом случае ТС можно посоветовать научиться не упоминать имен типов в sizeof и воспользоваться способом 3б по вышеприведенной ссылке

C++
1
2
3
4
5
matrix = static_cast<int **>(malloc(m * sizeof *matrix));
int *data = static_cast<int *>(malloc(m * n * sizeof *data));
 
for (int i = 0; i < m; ++i, data += n)
  matrix[i] = data;
0
Andrej
И целого heap'а мало
94 / 55 / 9
Регистрация: 31.07.2014
Сообщений: 291
20.11.2014, 23:31 #5
jake09,
C++
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
26
27
28
29
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <math.h>
 
int main()
{
   srand(time(NULL));
   const int size_x = 4, size_y = 5;
   const int m = size_x * size_y;
   int *matrix, i, j, d, n[4] = {1,2,3,4}, s;
   matrix = (int*) malloc(m * sizeof(int*));
   for (i = 0; i < size_x; i++)
   {
       for (j = 0; j < size_y; j++)
       {
           matrix[i * size_x + j] = (rand() % 20)-10;
           d = fabs(matrix[i * size_x + j]);
           if((j+1)==d)
           {
                  s++;
           }
       }
       printf("For line %d number of elements that matched is = %d\n", n[i],s);
   }
   free(matrix);
   return 0;
 
}
1
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
3909 / 2146 / 549
Регистрация: 18.10.2014
Сообщений: 3,755
20.11.2014, 23:34 #6
Цитата Сообщение от Andrej Посмотреть сообщение
matrix = (int*) malloc(m * sizeof(int*));
Снова та же ошибка с неправильным типом под sizeof. Должно быть

C++
1
matrix = (int*) malloc(m * sizeof(int));
Именно поэтому рекомендуемая идиоматическая форма - это

C++
1
matrix = (int*) malloc(m * sizeof *matrix);
Избавьтесь от вредной привычки упоминать типы в выражениях.
0
Andrej
И целого heap'а мало
94 / 55 / 9
Регистрация: 31.07.2014
Сообщений: 291
20.11.2014, 23:37 #7
TheCalligrapher, да знаю. Сам тут тоже вертел этими идиомами, да что-то народец не впитывает.
Студенту же нужно прогу написать, чтобы препод о******я, а не код-стайл впитать.

Не по теме:

В нормальном коде то такого конечно не напишу.

0
true_bugmaker
28 / 5 / 1
Регистрация: 18.11.2014
Сообщений: 68
21.11.2014, 00:09 #8
Как можно выделять двумерные динамические массивы...поэтому фраза "по факту в сях нету двумерных массивов" мне не совсем ясна.
С++ specification не указывает на наличие многомерных массивов как свойств языка. С++ лишь предоставляет некую сущность, которую можно использовать как многомерный массив, но это не есть многомерный массив. И отличие особенно видно на таких примерах как этот.

ISO/IEC JTC1 SC22 WG21 N 3690, § 8.3.4:
A consistent rule is followed for multidimensional arrays. If E is an n-dimensional array of rank i×j ×. . .×k,
then E appearing in an expression that is subject to the array-to-pointer conversion (4.2) is converted to a
pointer to an (n − 1)-dimensional array with rank j × . . . × k. If the * operator, either explicitly or implicitly
as a result of subscripting, is applied to this pointer, the result is the pointed-to (n − 1)-dimensional array,
which itself is immediately converted into a pointer.
0
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
3909 / 2146 / 549
Регистрация: 18.10.2014
Сообщений: 3,755
21.11.2014, 00:15 #9
Цитата Сообщение от true_bugmaker Посмотреть сообщение
С++ specification не указывает на наличие многомерных массивов как свойств языка.
Что значит "не указывает"? Вы же сам процитировали слова, в которых говорится о "multidimensional arrays".

Цитата Сообщение от true_bugmaker Посмотреть сообщение
С++ лишь предоставляет некую сущность, которую можно использовать как многомерный массив
"Сущность, которую можно использовать как многомерный массив" - это и есть многомерный массив Все остальное - детали реализации.

Цитата Сообщение от true_bugmaker Посмотреть сообщение
но это не есть многомерный массив.
Это почему это? Это какая-то голословная схоластика...

Цитата Сообщение от true_bugmaker Посмотреть сообщение
И отличие особенно видно на таких примерах как этот.
Этот пример просто говорит, что поведение array-to-pointer conversion единообразно для всех массивов, независимо от того, multidimensional они или нет. Никакого "особенно видно" я тут в упор не вижу.
0
true_bugmaker
28 / 5 / 1
Регистрация: 18.11.2014
Сообщений: 68
21.11.2014, 00:34 #10
Что значит "не указывает"? Вы же сам процитировали слова, в которых говорится о "multidimensional arrays".
Там далее проясняется что они на самом деле такое.

"Сущность, которую можно использовать как многомерный массив" - это и есть многомерный массив Все остальное - детали реализации.
Её нельзя использовать как многомерный массив во всех случаях. Например выделять и освобождать память без цикла. Почитай K&R 5.7, там понятно расписано.
0
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
3909 / 2146 / 549
Регистрация: 18.10.2014
Сообщений: 3,755
21.11.2014, 00:48 #11
Цитата Сообщение от true_bugmaker Посмотреть сообщение
Там далее проясняется что они на самом деле такое.
Там далее проясняется, что многомерный массив в С++ (как и в С) реализуется как одномерный массив с пересчетом индексов. Я в упор не вижу, как это вдруг "проясняет", что это не многомерный массив. (???)

Цитата Сообщение от true_bugmaker Посмотреть сообщение
Например выделять и освобождать память без цикла.
Чего? О каком цикле идет речь? Память "многомерного массива" в С и С++ состоит из одного непрерывного блока. Никакого "цикла" при выделении и/или освобождении памяти для такого массива нет и быть не может. Где это вы видели цикл при выделении и/или освобождении памяти для встроенного языкового массива? Примерчик не затруднит привести?

Цитата Сообщение от true_bugmaker Посмотреть сообщение
Почитай K&R 5.7, там понятно расписано.
Очевидно, несмотря на "понятность расписанного", вы все таки что-то неправильно поняли.
0
true_bugmaker
28 / 5 / 1
Регистрация: 18.11.2014
Сообщений: 68
21.11.2014, 01:06 #12
Чего? О каком цикле идет речь? Память "многомерного массива" в С и С++ состоит из одного непрерывного блока.
Где конкретно в спецификации это указано?

Никакого "цикла" при выделении и/или освобождении памяти для такого массива нет и быть не может. Где это вы видели цикл при выделении и/или освобождении памяти для встроенного языкового массива? Примерчик не затруднит привести?
http://www.cprogramming.com/tutorial/dynamic_memory_allocation.html

To deleted the allocated memory you must go through the first array and apply delete[] to every element and then delete[] the main one:
По-моему ты меня уныло троллишь. Если дискуссия с твоей стороны будет продолжаться в таком же стиле, я её прекращаю.
0
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
3909 / 2146 / 549
Регистрация: 18.10.2014
Сообщений: 3,755
21.11.2014, 02:01 #13
Цитата Сообщение от true_bugmaker Посмотреть сообщение
Где конкретно в спецификации это указано?
Это тянется еще со спецификации языка С.

В С++03, например, это указано в 8.3.4. Где сказано
8.3.4/1. Что массив 'T a[N]' является непрерывно распределенной последовательностью из 'N' объектов типа 'T' (An object of array type contains a contiguously allocated nonempty
set of N sub-objects of type T.)
8.3.4/2. Что типом 'T' может являться в том числе и другой массив (An array can be constructed from one of the fundamental types (except void), from a pointer, from a
pointer to member, from a class, from an enumeration type, or from another array.)
8.3.4/3. Что такой объект и является тем, что называется "многомерным массивом" в С++
8.3.4/4. Поясняет 8.3.4/3 примерами.

То есть в языке С++ N-мерный массив определяется рекурсивно как 1-мерный массив N-1-мерных подмассивов. И т.д.

Вы просто не поняли. Структура данных, которая создается в конце вашей ссылки - это так называемый "jagged array" (или "ragged array"). Эта структура данных ни по своему устройству, ни по своей семантике никакого отношения к встроенным многомерным массивам языка С++ не имеет.

Внешнее сходство сводится лишь к возможности применять [i][j] для доступа к элементам. Именно по этой причине новички зачастую наивно полагают, что именно так устроены встроенные языковые многомерные массивы. А на самом деле это не так.

Цитата Сообщение от true_bugmaker Посмотреть сообщение
По-моему ты меня уныло троллишь. Если дискуссия с твоей стороны будет продолжаться в таком же стиле, я её прекращаю.
Нет, нет, это просто вас кто-то раньше уныло и жестоко потроллил, причем с занесением в подсознание. Вот вы теперь "так и ходите", не понимая, что с вами сделали.

У вас сейчас есть уникальная возможность выкинуть весь этот мусор из головы и чему-то наконец научиться. Но для этого вы будете вести себя исключительно вежливо. Если что не понятно - будете задавать вежливые продуманные вопросы. А не устраивает - вперед колбаской по Малой Спасской!
0
true_bugmaker
28 / 5 / 1
Регистрация: 18.11.2014
Сообщений: 68
21.11.2014, 02:06 #14
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
То есть в языке С++ N-мерный массив определяется рекурсивно как 1-мерный массив N-1-мерных подмассивов. И т.д.
Я только недавно указывал на K&R и на спецификацию. Для int a[i][j], a[i] это массив указателей на массивы из целых чисел. Повторяю вопрос. Где в спецификации указано что эти массивы из целых чисел обязаны находиться в смежных областях памяти?

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
это так называемый "jagged array" (или "ragged array"). Эта структура данных ни по своему устройству, ни по своей семантике никакого отношения к встроенным многомерным массивам языка С++ не имеет.
То есть она не может использоваться как многомерный массив?
0
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
3909 / 2146 / 549
Регистрация: 18.10.2014
Сообщений: 3,755
21.11.2014, 02:21 #15
Цитата Сообщение от true_bugmaker Посмотреть сообщение
Я только недавно указывал на K&R и на спецификацию.
Очевидно, вы что-то неправильно поняли в K&R и/или в спецификации.

Цитата Сообщение от true_bugmaker Посмотреть сообщение
Для int a[i][j], a[i] это массив указателей на массивы из целых чисел.
Ни в коем случае!!! Никаких указателей там нет и никогда не было.

Если массив объявлен как 'int a[10][20]' и мы применяем к нему 'a[i][j]', то 'a[i]' - это i-тый объект типа 'int[20]' внутри 'a'. Это i-тый одномерный подмассив. Это подобъект типа "массив int[20]". И (ключевой момент!) в таком контексте он подвергается неявному стандартному преобразованию типа, называемому array-to-pointer conversion (cм. 4.2 в С++03). Это преобразование порождает временное значение - указатель на первый элемент подмассива 'a[i]' и далее работа идет уже с этим указателем.

Ключевой момент здесь в том, что никакие указатели физически нигде не хранятся. Никакого массива указателей нет и никогда не было. Указатель возникает только воображаемый, концептуальный, временный, как промежуточный результат выполнения array-to-pointer conversion.

Именно об этом подробно написано в той части спецификации, которую вы же сами и цитировали. Именно об этом написано и в K&R.

Добавлено через 1 минуту
Цитата Сообщение от true_bugmaker Посмотреть сообщение
То есть она не может использоваться как многомерный массив?
Почему не может? Может конечно. Я лишь говорю, что это другой способ представления многомерных массивов, который на физическом уровне отличается от представления встроенных многомерных массивов языков С и С++. У каждого способа свои преимущества, недостатки и области применения.

В частности, встроенный языковый массив 'T a[M][N]' требует ровно 'M * N * sizeof(T)' памяти. А вот "jagged array" требует сверх этого еще дополнительно 'M * sizeof(T *)' памяти для явного хранения массива указателей.
0
21.11.2014, 02:21
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.11.2014, 02:21
Привет! Вот еще темы с ответами:

Работа с массивом через указатели(Определить, строго ли чередуются элементы в массиве) - C++
Задан массив из N элементов, состоящий только из нулей и единиц. Определить, строго ли чередуются элементы в массиве. Программа должна...

лаба по динамеческим структурам данных - C++
Кто знает как сделать????

Не могу разобраться как сделать указатель функции с динамич. массивом - C++
int* mass(int p, int n) { cout &lt;&lt; &quot;Введите размер массива: &quot;; cin&gt;&gt;n; int *p = new int ; for (int i(0); i &lt; n; i ++) { cout &lt;&lt;...

Работа с файлом (передать указатель на файл в функцию, вернуть указатель на файл из функции) - C++
Подскажите как передать указатель на файл в функцию, как вернуть указатель на файл из функции. void Open() // из этой функции вернуть...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru