Очень часто возникают задачи обработки массивов данных, размерность которых заранее неизвестна. В этом случае возможно использование одного из двух подходов:
- выделение памяти под статический массив, содержащий максимально возможное число элементов, однако в этом случае память расходуется не рационально;
- динамическое выделение памяти для хранение массива данных.
Для использования функций динамического выделения памяти необходимо описать указатель, представляющий собой начальный адрес хранения элементов массива.
Начальный адрес статического массива определяется компилятором в момент его объявления и не может быть изменен.
Для динамического массива начальный адрес присваивается объявленному указателю на массив в процессе выполнения программы.
Стандартные функции динамического выделения памяти
Функции динамического выделения памяти находят в оперативной памяти непрерывный участок требуемой длины и возвращают начальный адрес этого участка.
Функции динамического распределения памяти:
void* calloc(ЧислоЭлементов, РазмерЭлементаВБайтах);
Для использования функций динамического распределения памяти необходимо подключение библиотеки <malloc.h>:
Поскольку обе представленные функции в качестве возвращаемого значения имеют указатель на пустой тип void, требуется явное приведение типа возвращаемого значения.
Для определения размера массива в байтах, используемого в качестве аргумента функции malloc() требуется количество элементов умножить на размер одного элемента. Поскольку элементами массива могут быть как данные простых типов, так и составных типов (например, структуры), для точного определения размера элемента в общем случае рекомендуется использование функции
которая определяет количество байт, занимаемое элементом указанного типа.
Память, динамически выделенная с использованием функций calloc(), malloc(), может быть освобождена с использованием функции
«Правилом хорошего тона» в программировании является освобождение динамически выделенной памяти в случае отсутствия ее дальнейшего использования. Однако если динамически выделенная память не освобождается явным образом, она будет освобождена по завершении выполнения программы.
Динамическое выделение памяти для одномерных массивов
Форма обращения к элементам массива с помощью указателей имеет следующий вид:
int b;
p = a; // присваиваем указателю начальный адрес массива
... // ввод элементов массива
b = *p; // b = a[0];
b = *(p+i) // b = a[i];
Пример на Си: Организация динамического одномерного массива и ввод его элементов.
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
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
int main()
{
int *a; // указатель на массив
int i, n;
system("chcp 1251");
system("cls");
printf("Введите размер массива: ");
scanf("%d", &n);
// Выделение памяти
a = (int*)malloc(n * sizeof(int));
// Ввод элементов массива
for (i = 0; i<n; i++)
{
printf("a[%d] = ", i);
scanf("%d", &a[i]);
}
// Вывод элементов массива
for (i = 0; i<n; i++)
printf("%d ", a[i]);
free(a);
getchar(); getchar();
return 0;
}
Результат выполнения программы:

Динамическое выделение памяти для двумерных массивов
Пусть требуется разместить в динамической памяти матрицу, содержащую n строк и m столбцов. Двумерная матрица будет располагаться в оперативной памяти в форме ленты, состоящей из элементов строк. При этом индекс любого элемента двумерной матрицы можно получить по формуле
index = i*m+j;
где i - номер текущей строки; j - номер текущего столбца.
Рассмотрим матрицу 3x4 (см. рис.)
Индекс выделенного элемента определится как
index = 1*4+2=6
Объем памяти, требуемый для размещения двумерного массива, определится как
n·m·(размер элемента)
Однако поскольку при таком объявлении компилятору явно не указывается количество элементов в строке и столбце двумерного массива, традиционное обращение к элементу путем указания индекса строки и индекса столбца является некорректным:
a[i][j] - некорректно.
Правильное обращение к элементу с использованием указателя будет выглядеть как
*(p+i*m+j),
где
- p - указатель на массив,
- m - количество столбцов,
- i - индекс строки,
- j - индекс столбца.
Пример на Си Ввод и вывод значений динамического двумерного массива
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
30
31
32
33
34
35
36
37
38
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
int main()
{
int *a; // указатель на массив
int i, j, n, m;
system("chcp 1251");
system("cls");
printf("Введите количество строк: ");
scanf("%d", &n);
printf("Введите количество столбцов: ");
scanf("%d", &m);
// Выделение памяти
a = (int*)malloc(n*m * sizeof(int));
// Ввод элементов массива
for (i = 0; i<n; i++) // цикл по строкам
{
for (j = 0; j<m; j++) // цикл по столбцам
{
printf("a[%d][%d] = ", i, j);
scanf("%d", (a + i*m + j));
}
}
// Вывод элементов массива
for (i = 0; i<n; i++) // цикл по строкам
{
for (j = 0; j<m; j++) // цикл по столбцам
{
printf("%5d ", *(a + i*m + j)); // 5 знакомест под элемент массива
}
printf("\n");
}
free(a);
getchar(); getchar();
return 0;
}
Результат выполнения
Возможен также другой способ динамического выделения памяти под двумерный массив - с использованием массива указателей. Для этого необходимо:
- выделить блок оперативной памяти под массив указателей;
- выделить блоки оперативной памяти под одномерные массивы, представляющие собой строки искомой матрицы;
- записать адреса строк в массив указателей.
Графически такой способ выделения памяти можно представить следующим образом.
При таком способе выделения памяти компилятору явно указано количество строк и количество столбцов в массиве.
Пример на Си
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
int main()
{
int **a; // указатель на указатель на строку элементов
int i, j, n, m;
system("chcp 1251");
system("cls");
printf("Введите количество строк: ");
scanf("%d", &n);
printf("Введите количество столбцов: ");
scanf("%d", &m);
// Выделение памяти под указатели на строки
a = (int**)malloc(n * sizeof(int*));
// Ввод элементов массива
for (i = 0; i<n; i++) // цикл по строкам
{
// Выделение памяти под хранение строк
a[i] = (int*)malloc(m * sizeof(int));
for (j = 0; j<m; j++) // цикл по столбцам
{
printf("a[%d][%d] = ", i, j);
scanf("%d", &a[i][j]);
}
}
// Вывод элементов массива
for (i = 0; i < n; i++) // цикл по строкам
{
for (j = 0; j < m; j++) // цикл по столбцам
{
printf("%5d ", a[i][j]); // 5 знакомест под элемент массива
}
printf("\n");
}
// Очистка памяти
for (i = 0; i < n; i++) // цикл по строкам
free(a[i]); // освобождение памяти под строку
free(a);
getchar(); getchar();
return 0;
}
Результат выполнения программы аналогичен предыдущему случаю.
С помощью динамического выделения памяти под указатели строк можно размещать свободные массивы. Свободным называется двухмерный массив (матрица), размер строк которого может быть различным. Преимущество использования свободного массива заключается в том, что не требуется отводить память компьютера с запасом для размещения строки максимально возможной длины. Фактически свободный массив представляет собой одномерный массив указателей на одномерные массивы данных.
Для размещения в оперативной памяти матрицы со строками разной длины необходимо ввести дополнительный массив m, в котором будут храниться размеры строк.
Пример на Си: Свободный массив
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <stdio.h>
#include <stdlib.h>
int main()
{
int **a;
int i, j, n, *m;
system("chcp 1251");
system("cls");
printf("Введите количество строк: ");
scanf("%d", &n);
a = (int**)malloc(n * sizeof(int*));
m = (int*)malloc(n * sizeof(int)); // массив кол-ва элеменов в строках массива a
// Ввод элементов массива
for (i = 0; i<n; i++)
{
printf("Введите количество столбцов строки %d: ", i);
scanf("%d", &m[i]);
a[i] = (int*)malloc(m[i] * sizeof(int));
for (j = 0; j<m[i]; j++) {
printf("a[%d][%d]= ", i, j);
scanf("%d", &a[i][j]);
}
}
// Вывод элементов массива
for (i = 0; i<n; i++)
{
for (j = 0; j<m[i]; j++)
{
printf("%3d ", a[i][j]);
}
printf("\n");
}
// Освобождение памяти
for (i = 0; i < n; i++)
{
free(a[i]);
}
free(a);
free(m);
getchar(); getchar();
return 0;
}
Результат выполнения

Перераспределение памяти
Если размер выделяемой памяти нельзя задать заранее, например при вводе последовательности значений до определенной команды, то для увеличения размера массива при вводе следующего значения необходимо выполнить следующие действия:
- Выделить блок памяти размерности n+1 (на 1 больше текущего размера массива)
- Скопировать все значения, хранящиеся в массиве во вновь выделенную область памяти
- Освободить память, выделенную ранее для хранения массива
- Переместить указатель начала массива на начало вновь выделенной области памяти
- Дополнить массив последним введенным значением
Все перечисленные выше действия (кроме последнего) выполняет функция
- ptr - указатель на блок ранее выделенной памяти функциями malloc(), calloc() или realloc() для перемещения в новое место. Если этот параметр равен NULL, то выделяется новый блок, и функция возвращает на него указатель.
- size - новый размер, в байтах, выделяемого блока памяти. Если size = 0, ранее выделенная память освобождается и функция возвращает нулевой указатель, ptr устанавливается в NULL.
Размер блока памяти, на который ссылается параметр ptr изменяется на size байтов. Блок памяти может уменьшаться или увеличиваться в размере. Содержимое блока памяти сохраняется даже если новый блок имеет меньший размер, чем старый. Но отбрасываются те данные, которые выходят за рамки нового блока. Если новый блок памяти больше старого, то содержимое вновь выделенной памяти будет неопределенным.
Пример на Си Выделить память для ввода массива целых чисел. После ввода каждого значения задавать вопрос о вводе следующего значения.
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
#include <stdio.h>
#include <malloc.h>
int main()
{
int *a = NULL, i = 0, elem;
char c;
do {
printf("a[%d]= ", i);
scanf("%d", &elem);
a = (int*)realloc(a, (i + 1) * sizeof(int));
a[i] = elem;
i++;
getchar();
printf("Next (y/n)? ");
c = getchar();
} while (c == 'y');
for (int j = 0; j < i; j++)
printf("%d ", a[j]);
if (i>2) i -= 2;
printf("\n");
a = (int*)realloc(a, i * sizeof(int)); // уменьшение размера массива на 2
for (int j = 0; j < i; j++)
printf("%d ", a[j]);
getchar(); getchar();
return 0;
}
Результат выполнения
Назад: Язык Си
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
#include <stdlib.h>
int main() {
int i,j,str, stolb;
int *arr;
printf("Vvedite kol-vo strok:");
scanf_s("%d", &str);
printf("\nVvedite kol-vo stol-ob:");
scanf_s("%d", &stolb);
arr = (int*)malloc(str * stolb * sizeof(int));
for (i = 0; i < str; i++) {
for (j = 0; j < stolb; j++) {
scanf_s("%d",(arr+(i*stolb)+j));
}
}
for (i = 0; i < str; i++) {
for (j = 0; j < stolb; j++) {
printf("%2d ", *(arr+(i * stolb) + j));
}
printf("\n");
}
return 0;
}
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
30
31
32
33
34
35
36
37
{
int N = 0;
int G = 0;
int M = 0, mas[4][4] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 };
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++)
{
printf("%d ", mas[i][j]);
}
printf("\n");
}
printf("\n");
for (int i = 0; i < 4; i++) {
for (int j = i + 1; j < 4; j++)
{
N = (abs(mas[1][3]) + abs(mas[1][3]) + abs(mas[1][3]) + abs(mas[1][1]) + abs(mas[1][1]));
printf("%d ", mas[i][j]);
}
printf("\n");
}
printf("\n");
for (int i = 1; i < 4; i++) {
for (int j = 0; j < i; j++) {
printf("%d ", mas[i][j]);
M = (abs(mas[1][2]) + abs(mas[1][2]) + abs(mas[1][3]) + abs(mas[1][3]) + abs(mas[1][3]) + abs(mas[3][1]) + abs(mas[3][1]));
}
printf("\n");
}
printf("%d ", N);
printf("%d ", M);
G = N - M;
printf("\n");
printf("%d ", G);
printf("\n");
}
4 4 10 3 5 1 9 2 7 3 12 6 8 2 20 9 11 5
матрица будет иметь вид:
10 3 5 1
9 2 7 3
12 6 8 2
20 9 11 5
вывод минимумов будет выглядеть так:
1 2 2
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
30
31
32
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
void allocate(/* нужные параметры указать тут */);
void fill(/* нужные параметры указать тут */);
void print(/* нужные параметры указать тут */);
void release(/* нужные параметры указать тут */);
void find_min(/* нужные параметры указать тут */);
int main(int argc, char const *argv[])
{
int NO_OF_COLS = 0;
int NO_OF_ROWS = 0;
scanf("%d%d", &NO_OF_ROWS, &NO_OF_COLS);
int ** matrix = NULL;
allocate(/* нужные аргументы передавать сюда */);
fill(/* нужные аргументы передавать сюда */);
print(/* нужные аргументы передавать сюда */);
find_min(/* нужные аргументы передавать сюда */);
release(/* нужные аргументы передавать сюда */);
assert(!matrix);
}
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
30
31
#include <stdio.h>
#include <stdlib.h>
void allocate(/* нужные параметры указать тут */);
void fill(/* нужные параметры указать тут */);
void print(/* нужные параметры указать тут */);
void release(/* нужные параметры указать тут */);
void find_min(/* нужные параметры указать тут */);
int main(int argc, char const *argv[])
{
int NO_OF_COLS = 0;
int NO_OF_ROWS = 0;
scanf("%d%d", &NO_OF_ROWS, &NO_OF_COLS);
int ** matrix = NULL;
allocate(/* нужные аргументы передавать сюда */);
fill(/* нужные аргументы передавать сюда */);
print(/* нужные аргументы передавать сюда */);
find_min(/* нужные аргументы передавать сюда */);
release(/* нужные аргументы передавать сюда */);
assert(!matrix);
}
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <malloc.h>
#include <stdlib.h>
int main()
{
int **a; // указатель на указатель на строку элементов
int i, j, n, m;
system("chcp 1251");
system("cls");
printf("Введите количество строк: ");
scanf("%d", &n);
printf("Введите количество столбцов: ");
scanf("%d", &m);
// Выделение памяти под указатели на строки
a = (int**)malloc(n * sizeof(int*));
if (a==NULL) { printf("Память не выделена\n"); exit(1); }
// Ввод элементов массива
for (i = 0; i<n; i++) // цикл по строкам
{
// Выделение памяти под хранение строк
a[i] = (int*)malloc(m * sizeof(int));
if (a[i]== NULL) { printf("Память не выделена\n"); n= i; goto ALARM; }
for (j = 0; j<m; j++) // цикл по столбцам
{
printf("a[%d][%d] = ", i, j);
scanf("%d", &a[i][j]);
}
}
// Вывод элементов массива
for (i = 0; i < n; i++) // цикл по строкам
{
for (j = 0; j < m; j++) // цикл по столбцам
{
printf("%5d ", a[i][j]); // 5 знакомест под элемент массива
}
printf("\n");
}
// Очистка
ALARM:
for (int ii = 0; ii < n; ii++) // цикл по строкам
free(a[ii]); // освобождение памяти под строку
free(a);
getchar(); getchar();
return 0;
}
2
double y = x;
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <cstdlib>
#include <ctime>
#include <clocale>
#include <iostream>
#include <malloc.h>
#define S 5
using namespace std;
void two_dim_input(int** a)
{
srand(time(0));
for (int i = 0; i < S; i++)
{
for (int u = 0; u < S; u++)
{
*((int*)a + i * S + u) = rand() % 99;
}
}
}
int main()
{
int** mas = (int **)calloc(S, sizeof(*mas));
for (int i = 0; i < S; i++)
*(mas + i) = (int *)calloc(S, sizeof(mas));
two_dim_input(mas);
two_dim_output(mas);
two_dim_sum(mas);
printf("\n\n");
two_dim_output(mas);
for (int i = 0; i < S; i++) // цикл по строкам
free(mas[i]); // освобождение памяти под строку
free(mas);
}
2
3
4
5
6
7
8
...
int** mas = (int**)calloc(S, sizeof(int*));
for (int i = 0; i < S; i++)
*(mas + i) = (int*)calloc(S, sizeof(int)); // не sizeof(mas)
...
for (int i = 0; i < S; i++) // цикл по строкам
free(*(mas+i)); // освобождение памяти под строку
2
3
if (!a)
return (NULL);
2
3
4
5
6
{
free(elem_arr[i]);
i++;
}
return (NULL); // далее возвращаю NULL
2
3
4
5
6
7
8
9
10
11
12
13
cout << "_asm code started working" << endl;
_asm {
pushf // помещаем регистр флагов в стек
pop var // извлекаем операнд из стека (шта?)
}
cout << "_asm code finished working" << endl;
// Вывод var
cout << var << endl;
2
3
4
5
6
7
8
9
10
11
12
13
var = new short[1];
cout << "_asm code started working" << endl;
_asm {
pushf // помещаем регистр флагов в стек
pop *var[0] // извлекаем операнд из стека (шта?)
}
cout << "_asm code finished working" << endl;
// Вывод var
cout << *var[0] << endl;
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include <stdlib.h>
#include <time.h>
#include <malloc.h>
int main()
{
system("chcp 1251"); system("cls");
srand(time(NULL));
int* b, n, m;
printf("кол-во строк: "); scanf_s("%d", &n);
printf("кол-во столбцов: "); scanf_s("%d", &m);
b = (int*)malloc(n * m * sizeof(int));
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++)
*(b + i * m + j) = rand() % 100;
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
printf("%4d", *(b + i * m + j));
}
printf("\n");
}
int max, maxi = 0, maxj = 0;
max = *b;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++)
if (*(b + i * m + j) == max) {
continue;
}
else if (*(b + i * m + j) > max) {
max = *(b + i * m + j);
maxi = i;
maxj = j;
}
}
printf("\nMax = %d", max);
printf("\nmaxi = %d", maxi);
printf("\nmaxj = %d", maxj);
if (maxi > 0) {
for (int i = maxi; i < n; i++) {
for (int j = 0; j < m; j++) {
*(b + (i - 1) * m + j) = *(b + i * m + j);
}
}
n--;
printf("\nматрица после удаления строки\n\n");
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
printf("%4d", *(b + i * m + j));
}
printf("\n");
}
m++;
for (int i = 0; i < n; i++) {
for (int j = m - 1; j > maxj - 1; j--) {
*(b + i * m + j) = *(b + i * m + (j - 1)); //зміщуємо стовбчики вправо
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
*(b + i * m + maxj) = rand() % 100;
}
}
printf("\nматрица после добавления столбца\n\n");
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
printf("%4d", *(b + i * m + j));
}
printf("\n");
}
return 0;
}
else return 0;
}
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
for (int j = 0; j < m; j++) {
*(b + i * m + j) = *(b + (i+1) * m + j);
}
}
n--;
printf("\nматрица после удаления строки\n\n");
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
printf("%4d", *(b + i * m + j));
}
printf("\n");
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < maxj; j++) {
*(b + i * (m-1) + j) = *(b + i * m + j); //сдвигаем столбцы влево
}
for (int j = maxj+1; j < m; j++) {
*(b + i * (m-1) + j-1) = *(b + i * m + j); //сдвигаем столбцы влево
}
}
m--;
printf("\nматрица после удаления столбца\n\n");
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
printf("%4d", *(b + i * m + j));
}
printf("\n");
}
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
30
31
32
33
34
35
36
37
38
#include <stdlib.h>
#include <time.h>
#include <malloc.h>
int main()
{
system("chcp 1251"); system("cls");
srand(time(NULL));
int* b, n, m;
printf("кол-во строк "); scanf_s("%d", &n);
printf("кол-во столбцов: "); scanf_s("%d", &m);
b = (int*)malloc(n * m * sizeof(int));
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++)
*(b + i * m + j) = rand() % 100;
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++)
printf("%4d", *(b + i * m + j));
}
int max, maxi = 0, maxj = 0;
max = *b;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++)
if (*(b + i * m + j) == max) {
continue;
}
else if (*(b + i * m + j) > max) {
max = *(b + i * m + j);
maxi = i;
maxj = j;
}
}
printf("\nMax = %d", max);
printf("\nmaxi = %d", maxi);
printf("\nmaxj = %d", maxj);
}
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include "stdlib.h"
#include "stdio.h"
#include "conio.h"
#include "math.h"
#include <malloc.h>
#include "locale.h"
#include "string.h"
#include "windows.h"
#include "time.h"
int main()
{
int** a; // указатель на указатель на строку элементов
int** b; // указатель на указатель на строку элементов
int i, j, n, m;
int counter = 0;
system("chcp 1251");
system("cls");
printf("Введите количество строк: ");
scanf("%d", &n);
printf("Введите количество столбцов: ");
scanf("%d", &m);
// Выделение памяти под указатели на строки
a = (int**)malloc(n * sizeof(int*));
// Ввод элементов массива
for (i = 0; i < n; i++) // цикл по строкам
{
// Выделение памяти под хранение строк
a[i] = (int*)malloc(m * sizeof(int));
for (j = 0; j < m; j++) // цикл по столбцам
{
printf("a[%d][%d] = ", i, j);
scanf("%d", &a[i][j]);
}
}
// Вывод элементов массива
for (i = 0; i < n; i++) // цикл по строкам
{
for (j = 0; j < m; j++) // цикл по столбцам
{
printf("%5d ", a[i][j]); // 5 знакомест под элемент массива
}
printf("\n");
}
b = (int**)malloc(n * sizeof(int*));
// Ввод элементов массива
for (i = 0; i < n; i++) // цикл по строкам
{
// Выделение памяти под хранение строк
b[i] = (int*)malloc(m * sizeof(int));
for (j = 0; j < m; j++) // цикл по столбцам
{
printf("a[%d][%d] = ", i, j);
scanf("%d", &b[i][j]);
}
}
for (i = 0; i < n; i++) // цикл по строкам
{
for (j = 0; j < m; j++) // цикл по столбцам
{
printf("%5d ", b[i][j]); // 5 знакомест под элемент массива
}
printf("\n");
}
a = (int**)realloc(a, (2*n*m) * sizeof(int));
for (i = n; i < 2*n; i++) // цикл по строкам
{
for (j = 0; j < m; j++) // цикл по столбцам
{
a[i][j] = b[counter][j];
counter++;
}
printf("\n");
}
for (i = 0; i < 2*n; i++) // цикл по строкам
{
for (j = 0; j < m; j++) // цикл по столбцам
{
printf("%5d ", a[i][j]); // 5 знакомест под элемент массива
}
printf("\n");
}
// Очистка памяти
for (i = 0; i < n; i++) // цикл по строкам
free(a[i]); // освобождение памяти под строку
free(a);
for (i = 0; i < n; i++) // цикл по строкам
free(b[i]); // освобождение памяти под строку
free(b);
getchar();
return 0;
}
2
3
4
5
6
7
8
9
10
for (i = n; i < 2*n; i++) // цикл по строкам
{
a[i] = (int*)malloc(m * sizeof(int));
for (j = 0; j < m; j++) // цикл по столбцам
{
a[i][j] = b[counter][j];
counter++;
}
}
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
30
31
32
33
34
35
36
37
38
39
40
41
42
#include "math.h"
#include "windows.h"
#include "stdlib.h"
#include <locale.h>
int _tmain(int argc, _TCHAR* argv[])
{ setlocale(0,"rus");
int i,j,i_,j_,N,M,*A,buf,min=10000,k,d=0;
printf("Введите размеры матрицы A");
scanf("%i %i",&N,&M);
A = (int*)malloc(N*M * sizeof(int));
printf("Матрица:\n");
for(i=0; i<N; i++)
{printf("\n");
for(j=0; j<M; j++)
{*(A+i*N+j)=-2 + rand()%(2-(-2)+1);
printf("%2i ",*(A+i*N+j));}}
do{d++;
for(j=0; j<M; j++)
{for(k=0; k<N-1; k++) {min=k;
for(i=k+1; i<N; i++){
if (*(A+i*N+j)==0 || *(A+min*N+j)==0) {continue;}
if (*(A+min*N+j)<*(A+i*N+j)) {min=i;}
else{ buf=*(A+min*N+j);
*(A+min*N+j)=*(A+i*N+j);
*(A+i*N+j)=buf;}}}}
}while (d<2);
printf("\n Преобразование:");
for(i=0; i<N; i++)
{printf("\n");
for(j=0; j<M; j++)
printf("%2i ",*(A+i*N+j));}
printf("\n");
system("pause");
return 0;
}
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
30
31
32
33
34
35
36
37
38
for (i = 0; i < N; i++)
{
printf("\n");
for (j = 0; j < M; j++)
{
*(A + i * M + j) = -2 + rand() % (2 - (-2) + 1);
printf("%2d ", *(A + i * M + j));
}
}
for (j = 0; j < M; j++)
{
int has0 = 0;
for (k = 0; k < N; k++)
{
if (*(A + k * M + j) == 0)
{
has0 = 1; break;
}
}
if (has0 == 1) continue;
for (k = 0; k < N - 1; k++)
{
min = k;
for (i = k + 1; i < N; i++)
{
if (*(A + i * M + j) < *(A + min*M + j))
{
min = i;
}
}
int buf = *(A + k * M + j);
*(A + k * M + j) = *(A + min * M + j);
*(A + min * M + j) = buf;
}
}
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
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <conio.h>
#include <malloc.h>
#include <stdlib.h>
int main() {
int i, j, k, s, m;
printf("Power: ", s);
scanf_s("%d", s);
double *a;
double b[3][3];
a = (double*)malloc(3 * 3 * sizeof(double));
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
printf("a[%d][%d] = ", i, j);
scanf_s("%lf", (a + i * 3 + j));
}
}
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
printf("%.2lf ", (a + i * 3 + j));
}
printf("\n");
}
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++)
{
b[i][j] = 1;
for (m = 1; m <= s; m++) {
b[i][j] *= a[j][i];
}
}
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
printf("%.3lf ", (b + i * 3 + j));
}
printf("\n");
}
free(a);
free(b);
_getch();
return 0;
}
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <conio.h>
#include <malloc.h>
#include <stdlib.h>
int main()
{
int i, j, k, s, m;
printf("Power: ");
scanf_s("%d", &s);
double* a;
double b[3][3];
a = (double*)malloc(3 * 3 * sizeof(double));
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
printf("a[%d][%d] = ", i, j);
scanf_s("%lf", (a + i * 3 + j));
}
}
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
printf("%.2lf ", *(a + i * 3 + j));
}
printf("\n");
}
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++)
{
b[i][j] = 1;
for (m = 1; m <= s; m++) {
b[i][j] *= *(a + i * 3 + j);
}
}
}
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
printf("%.3lf ", b[i][j]);
}
printf("\n");
}
free(a);
_getch();
return 0;
}
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <stdlib.h>
#include "locale.h"
#include <malloc.h>
#include <math.h>
#define _CRT_SECURE_NO_WARNINGS
double func(int n,int m,double **arr,int count1,int count2,double changer);
int main()
{
int count1=0,count2=0,n=0,m=0;
double changer=0;
double **arr;
printf("Введите количество строк: ");
scanf("%d", &n);
printf("Введите количество столбцов: ");
scanf("%d", &m);
arr = (double*)malloc(n*m * sizeof(double));
for (count1=0;count1<n;count1++)
{
for (count2=0;count2<m;count2++)
{
printf("arr[%d][%d] = ", count1, count2);
scanf("%fl", (arr + count1*m + count2));
printf("%lf\t",*(arr + count1*m + count2));
}
printf("\n");
}
for (count1=0;count1<n;count1++)
{
for (count2=0;count2<m;count2++)
{
printf("%lf\t",*(arr + count1*m + count2));
}
printf("\n");
}
func(arr,count1,count2,changer,n,m);
printf("\n");
for (count1=0;count1<n;count1++)
{
for (count2=0;count2<m;count2++)
{
printf("%lf\t",*(arr + count1*m + count2));
}
printf("\n");
}
}
double func(int n,int m,double **arr,int count1,int count2,double changer)
{
for (count2=0;count2<m;count2++)
{
changer=arr[0][count2];
for (count1=0;count1<n-1;count1++)
{
arr[count1][count2]=arr[count1+1][count2];
}
arr[n-1][count2]=changer;
}
return **arr;
}
2
3
4
5
6
mass = (int**)malloc(n * sizeof(int*));
for (int i = 0; i < n; i++)
{
mass[i] = (int*)malloc(m * sizeof(int));
}
2
3
4
5
for (int i = 0; i < (n+1); i++)
{
mass[i] = (int*)realloc(NULL,m * sizeof(int));
}
2
3
4
5
for (int i = 0; i < (n+1); i++)
{
mass[i] = (int*)malloc(m * sizeof(int));
}
2
mass[n] =(int*)malloc(m * sizeof(int));
2
3
4
5
6
mass[n] =(int*)malloc((m+1)* sizeof(int));
for (int i = 0; i < n; i++)
{
mass[i] = (int*)realloc(mass[i], (m+1)* sizeof(int));
}
2.В чем разница между функциями malloc и calloc?
3.В приведенных примерах программ в части ввода элементов массива при использовании функции scanf в списке аргументов в некоторых указывается амперсанд (&) - организация динамического одномерного массива, двумерного массива с использованием указателей, свободного массива, но в обычном динамическом двумерном массиве нет. Почему?
Заранее спасибо за ответы!
2. Функция calloc при выделении памяти обнуляет ее содержимое и, соответственно, выполняется несколько дольше.
3. Аргументом функции scanf является адрес. Амперсанд указывается в аргументе scanf если мы работаем с переменной (в этом случае амперсанд - это адрес переменной), а не с указателем. Если мы выделяем единую область памяти под двумерный массив, то обращаться к его элементам через индексы строки и столбца не получится, т.к. в этой единой области памяти не указано явно, сколько в массиве строк и сколько столбцов. В этом случае приходится обращаться к элементам массива через указатель (a+i*m+j), где m - количество столбцов. А этот указатель как раз и является адресом элемента a[i][j].
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
30
31
32
#include <stdlib.h>
#include <conio.h>
void sort()//функция нахождения числа делителей и сортировки
{
}
int main(void) {
int n;
int m;
m = 0;
printf("a[n],n=...\n");//число элементов в массиве
scanf("%i", &n);
int a[n];
int i;
for (i = 0; i < n; i++)//задание значений каждого из элементов
{
printf("number %i=", i);
scanf("%i", &a[i]);
}
sort(a, n);//выполнение функции по сортировке элементов массива
for (int i = 0; i < n; ++i)/*вывод элементов в порядке возрастания их
числа делителей*/
{
printf("%i ", a[i]);
}
getch();
return 0;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
/*Однако мне удалось реализовать алгоритм поиска делителей отдельного числа*/
int main(void) {
int x;
int i;
int m;
m = 0;
printf("enter x...");
scanf("%i", &x);//прием значения переменной с клавиатуры
for (i = 1; i <= x; i++)/*цикл для вычисления числа делителей
заданной переменной*/
{
if (x % i == 0)
m++;
}
printf("m=%i", m);//вывод числа делителей
return 0;
}
2
3
4
5
6
{
float m = A[i][i];
A[i][i] = A[i][N - i - 1];
A[i][N - i - 1] = m;
}
2
3
4
5
6
{
float m = *(A + i * N + i);
*(A + i * N + i) = *(A + i * N - i - 1);
*(A + i * N - i - 1) = m;
}
2
3
4
5
6
7
8
9
10
11
12
13
{
for(unsigned char i = 0; i < R; i++)
{
for(unsigned char j = 0; j < C; j++)
{
printf(" %5d ", *(*(point + i) + j));
}
printf("\n");
}
}
ну и вызов функции как
showMass(&data[0], r, c);
2
3
printf("Next (y/n)? ");
c = getchar();
Аналогичным образом действует двойной getchar() в конце программы.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <conio.h>
#define ESC 27
#define EOS ′\n′
using namespace std;
int main() {
int *a, temp = 0, i = 0;
a = (int*)malloc(temp*sizeof(int));
do {
cout << "Enter Numbers: ";
do {
cin >> a[temp];
temp++;
} while (cin.get() != EOS);
cout << "Result achived: ";
for (i, temp; temp > 0; temp−−, i++) {
cout << a[i] << " ";
}
} while (_getch() != ESC);
return 0;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#define ESC 27
#define EOS '\n'
using namespace std;
int main() {
int *a, temp, i;
do {
system("CLS");
temp = 0, i = 0;
a = (int*)malloc(sizeof(int));
cout << "Enter Numbers: ";
do {
cin >> a[temp];
temp++;
if (temp >= (sizeof(a) / sizeof(*a)))
a = (int*)realloc(a, (temp + 1) * sizeof(int));
} while (cin.get() != EOS);
cout << "Result achived: ";
for (i, temp; temp > 0; temp--, i++)cout << a[i] << " ";
free(a);
} while (_getch() != ESC);
return 0;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int *a; // указатель на массив
int i, n;
system("chcp 1251");
system("cls");
printf("Введите размер массива: ");
scanf("%d", &n);
// Выделение памяти
a = (int*) malloc(n*sizeof(int));
// Ввод элементов массива
for(i=0; i<n; i++)
{
printf("a[%d] = ", i);
scanf("%d", &a[i]);
}