Форум программистов, компьютерный форум, киберфорум
C для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.96/75: Рейтинг темы: голосов - 75, средняя оценка - 4.96
86 / 86 / 30
Регистрация: 12.08.2014
Сообщений: 1,129
1

Создание двумерного массива

16.03.2017, 00:55. Показов 14155. Ответов 11
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте! Столкнулся с такой проблемой: как правильно создать двумерный массив в Си? Все, что ни пытался найти - все ведет на с++, но никак ни на си. Поясню, мне нужно создать массив по такому принципу:
C
1
2
3
 scanf("N= %d", &N);
 scanf("M= %d", &M);
    int matrix[N][M];
Но! Будет ли такой способ правильным для создания массива?
Просто я всегда делал массивы в си таким образом:
C
1
2
scanf("N= %d", &N);
int*tab=(int*)maloc(sizeof(int)*N);
Скажите, может есть вариант создания двумерного массива как с одномерным? Или такой способ, как я написал тоже правильный? Спасибо!
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
16.03.2017, 00:55
Ответы с готовыми решениями:

Создание двумерного массива с элементами, зависящими от размера массива.
Помогите, пожалуйста решить задачу следующего характера на C: пользователь вводит размер массива...

Создание двумерного массива в программе
:cry:Рабочие изготавливают различные изделия. Рассчитать зарплату для каждого рабочего, учитывая,...

Создание двумерного динамического массива
Доброго времени суток. Нужно создать двумерный динамический массив (не используя указатели): ...

Динамическое создание двумерного массива
Например, такой код вызывает segmentation fault int **a = calloc(25*25,4); a=100500; а...

11
Велосипедист...
353 / 220 / 73
Регистрация: 15.12.2015
Сообщений: 785
16.03.2017, 02:44 2
Лучший ответ Сообщение было отмечено paskalnikita как решение

Решение

Цитата Сообщение от paskalnikita Посмотреть сообщение
Поясню, мне нужно создать массив по такому принципу:
C
1
2
3
 scanf("N= %d", &N);
 scanf("M= %d", &M);
    int matrix[N][M];
Но! Будет ли такой способ правильным для создания массива?
Нет, не будет, ибо N и M должны быть константами времени компиляции. Таким образом создается "статический массив". Если такой массив создается в функции -- он создается на стеке.

Цитата Сообщение от paskalnikita Посмотреть сообщение
Просто я всегда делал массивы в си таким образом:
C
1
2
scanf("N= %d", &N);
int*tab=(int*)malloc(sizeof(int)*N);
Так Вы создавали "динамический массив". Он располагается в куче.

Про стек и кучу почитайте, если не ознакомлены. Узнаете много чего интересного


К вопросу:
Цитата Сообщение от paskalnikita Посмотреть сообщение
Создание двумерного массива
Объявляем статический массив (когда размерность известна нам):
C
1
2
3
4
5
6
7
8
9
10
11
12
13
#define R 2
#define C 5
 
int main(void)
{
  int arr[R][C];
 
  for (int i = 0; i < R; ++i)
    for (int j = 0; j < C; ++j)
      printf("arr[%d][%d] = %d\n", i, j, arr[i][j]);
 
  return 0;
}
Объявляем динамический массив (когда размерность задается во время выполнения программы):
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int main(void)
{
  int R, C;
  scanf("%d%d", &R, &C);
 
  int** arr = (int **)malloc( sizeof(int *) * R );  // Создали указатель на массив указателей на int
  for (int i = 0; i < R; ++i)
    arr[i] = (int *)malloc( sizeof(int) * C );  // Каждому указателю на int, присваиваем массив типа int
 
  for (int i = 0; i < R; ++i)
    for (int j = 0; j < C; ++j)
      printf("arr[%d][%d] = %d\n", i, j, arr[i][j]);
 
 
  for (int i = 0; i < R; ++i)
    free(arr[i]);
  free(arr);
 
  return 0;
}
Как-то так)
1
1786 / 1036 / 445
Регистрация: 12.05.2016
Сообщений: 2,550
16.03.2017, 04:47 3
Цитата Сообщение от paskalnikita Посмотреть сообщение
C
1
2
3
scanf("N= %d", &N);
scanf("M= %d", &M);
int matrix[N][M];
Цитата Сообщение от paskalnikita Посмотреть сообщение
Но! Будет ли такой способ правильным для создания массива?
В принципе да, но не на всех компиляторах поддерживается(на gcc прокатит, а VS, вроде, не умеет VLA). П.С. лучше unsigned или size_t для размерностей указывать.
0
Вездепух
Эксперт CЭксперт С++
11696 / 6375 / 1724
Регистрация: 18.10.2014
Сообщений: 16,071
16.03.2017, 07:03 4
Лучший ответ Сообщение было отмечено paskalnikita как решение

Решение

Цитата Сообщение от paskalnikita Посмотреть сообщение
Будет ли такой способ правильным для создания массива?
Именно в С: да, будет. При условии что общий размер массива не является слишком большим для локальной переменной.

Но даже и в этом случае у вас будет вариант

C
1
int (*matrix)[N][M] = malloc(sizeof *matrix);
Добавлено через 1 минуту
Цитата Сообщение от Captain Maxee Посмотреть сообщение
Нет, не будет, ибо N и M должны быть константами времени компиляции.
В случае локального массива - нет, в языке С такого требования нет.
4
Велосипедист...
353 / 220 / 73
Регистрация: 15.12.2015
Сообщений: 785
16.03.2017, 16:50 5
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Цитата Сообщение от Captain Maxee Посмотреть сообщение
Нет, не будет, ибо N и M должны быть константами времени компиляции.
В случае локального массива - нет, в языке С такого требования нет.
Спасибо.
0
86 / 86 / 30
Регистрация: 12.08.2014
Сообщений: 1,129
17.03.2017, 18:56  [ТС] 6
TheCalligrapher, сделал так как Вы посоветовали, только проблема в том, что я не могу присвоить значения элементам массива. Делаю я это так:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
   srand(time(NULL));
    int N, M;
    printf("N= ");
    scanf("%d",&N);
    printf("M= ");
    scanf("%d",&M);
   int element;
   int (*matrix)[N][M] = malloc(sizeof *matrix);
    for (int i = 0; i < N; ++i){
        for (int j = 0; j < M ; ++j){
            element=rand()%41;
            matrix[i][j]=element;
        }
    }
return 0;
}
0
Вездепух
Эксперт CЭксперт С++
11696 / 6375 / 1724
Регистрация: 18.10.2014
Сообщений: 16,071
17.03.2017, 19:20 7
Цитата Сообщение от paskalnikita Посмотреть сообщение
не могу присвоить значения элементам массива
Если массив выделялся как

C
1
int (*matrix)[N][M] = malloc(sizeof *matrix);
то дальнейшая работа с массивом должна выглядеть так

C
1
(*matrix)[i][j] = element;
Альтернативно, можно выделить массив как

C
1
int (*matrix)[M] = malloc(N * sizeof *matrix);
и далее работать с ним так

C
1
matrix[i][j] = element;
Выберите, какой вариант вам больше нравится.
1
86 / 86 / 30
Регистрация: 12.08.2014
Сообщений: 1,129
21.06.2017, 13:05  [ТС] 8
Скажите, для такого варианта :
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
int (*matrix)[N][M] = malloc(sizeof *matrix);
есть что-нибудь вроде аналога? Поясню, сегодня узнал, что такой вариант выделения памяти не самый хороший. То есть, в таком случае выделяется память в которой есть указанное количество слотов памяти, а не так, что ищется много случайных свободных слотов. То есть есть память 00000 я выделил два слота для нее и в таком случае выделяется два последовательных слота памяти типа так --000 и это не очень правильно, так как не факт что есть такая длинная последовательность слотов памяти и лучше сделать что-то вроде такого: 0-0-0 или 00-0- и тд. Надеюсь понятно написал. Поправьте если не прав.

Добавлено через 5 минут
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
int (*matrix)[M] = malloc(N * sizeof *matrix);
и это вариант тоже аналогичен тому, что выше
0
440 / 432 / 159
Регистрация: 21.05.2016
Сообщений: 1,338
21.06.2017, 13:16 9
Цитата Сообщение от paskalnikita Посмотреть сообщение
Скажите, для такого варианта :

есть что-нибудь вроде аналога? Поясню, сегодня узнал, что такой вариант выделения памяти не самый хороший. То есть, в таком случае выделяется память в которой есть указанное количество слотов памяти, а не так, что ищется много случайных свободных слотов. То есть есть память 00000 я выделил два слота для нее и в таком случае выделяется два последовательных слота памяти типа так --000 и это не очень правильно, так как не факт что есть такая длинная последовательность слотов памяти и лучше сделать что-то вроде такого: 0-0-0 или 00-0- и тд. Надеюсь понятно написал. Поправьте если не прав.
Память (виртуальная) всегда выделяется одним куском, никаких случайных слотов
1
86 / 86 / 30
Регистрация: 12.08.2014
Сообщений: 1,129
21.06.2017, 13:21  [ТС] 10
Цитата Сообщение от oldnewyear Посмотреть сообщение
Память всегда выделяется одним куском, никаких случайных слотов
Вы уверены? нет такого, что есть самый оптимальный вариант выделения памяти? Нет такого, что функция malloc ищет первый свободный слот потом второй,третий и тд.? Есть ли подтверждение тому, что Вы пишете? Желательно на английском. Просто сегодня преподавать в университете сказал, что я не оптимально выделю память и лучше выделять по-другому и рассказал мне про способ, что я описал выше.
0
440 / 432 / 159
Регистрация: 21.05.2016
Сообщений: 1,338
21.06.2017, 13:38 11
Цитата Сообщение от paskalnikita Посмотреть сообщение
Вы уверены? нет такого, что есть самый оптимальный вариант выделения памяти? Нет такого, что функция malloc ищет первый свободный слот потом второй,третий и тд.? Есть ли подтверждение тому, что Вы пишете? Желательно на английском. Просто сегодня преподавать в университете сказал, что я не оптимально выделю память и лучше выделять по-другому и рассказал мне про способ, что я описал выше.
A single call to malloc allocates a contiguous chunk of heap space of the passed size
https://www.cs.swarthmore.edu/... rrays.html

Добавлено через 12 минут
Без всяких ссылок же должно быть понятно, маллок выделяет кусок памяти и присваивает указателю адрес начала этого куска. Определенно это должен быть один кусок, а как иначе. В физической памяти он может быть раскидан по разным фреймам, но это никак не контролируется юзером
1
Велосипедист...
353 / 220 / 73
Регистрация: 15.12.2015
Сообщений: 785
21.06.2017, 18:42 12
paskalnikita, возможно, Ваш преподаватель говорил о таком понятии как списки, просто Вы не так его поянли.
0
21.06.2017, 18:42
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
21.06.2017, 18:42
Помогаю со студенческими работами здесь

Создание двумерного массива в функции
Здравствуйте. У меня есть код и я хочу его понять. Здесь я создаю двумерный массив. Правильно ли я...

Создание двумерного динамического массива в функции
Здравствуйте. Помогите мне пожалуйста. При создании двумерного динамического массива через функцию...

Не работает динамическое создание двумерного массива
Добрый вечер. Не могу понять, почему не работает программа. Какие бы значения я не задавал (кроме...

Динамическое создание двумерного массива символов
Добрый день всем. Есть строка. В ней присутствуют разделители. необходимо из этой строки...


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru