Главная Случайная страница


Полезное:

Как сделать разговор полезным и приятным Как сделать объемную звезду своими руками Как сделать то, что делать не хочется? Как сделать погремушку Как сделать так чтобы женщины сами знакомились с вами Как сделать идею коммерческой Как сделать хорошую растяжку ног? Как сделать наш разум здоровым? Как сделать, чтобы люди обманывали меньше Вопрос 4. Как сделать так, чтобы вас уважали и ценили? Как сделать лучше себе и другим людям Как сделать свидание интересным?


Категории:

АрхитектураАстрономияБиологияГеографияГеологияИнформатикаИскусствоИсторияКулинарияКультураМаркетингМатематикаМедицинаМенеджментОхрана трудаПравоПроизводствоПсихологияРелигияСоциологияСпортТехникаФизикаФилософияХимияЭкологияЭкономикаЭлектроника






Динамическое выделение памяти для двумерных массивов





Пусть требуется разместить в динамической памяти матрицу, содержащую 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 - индекс столбца.

Пример Ввод и вывод значений динамического двумерного массива

#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;

}

Результат выполнения

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

· выделить блок оперативной памяти под массив указателей;

· выделить блоки оперативной памяти под одномерные массивы, представляющие собой строки искомой матрицы;

· записать адреса строк в массив указателей.

Графически такой способ выделения памяти можно представить следующим образом.

При таком способе выделения памяти компилятору явно указано количество строк и количество столбцов в массиве.

Пример

#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");

free(a[i]); // освобождение памяти под строку

}

free(a);

getchar(); getchar();

return 0;

}

Результат выполнения программы аналогичен предыдущему случаю.

С помощью динамического выделения памяти под указатели строк можно размещать свободные массивы. Свободным называется двухмерный массив (матрица), размер строк которого может быть различным. Преимущество использования свободного массива заключается в том, что не требуется отводить память компьютера с запасом для размещения строки максимально возможной длины. Фактически свободный массив представляет собой одномерный массив указателей на одномерные массивы данных.

Для размещения в оперативной памяти матрицы со строками разной длины необходимо ввести дополнительный массив m, в котором будут храниться размеры строк.

Пример

#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)); // массивкол-ваэлементовстрок

// Ввод элементов массива

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");

}

getchar(); getchar();

return 0;

}

Результат выполнения

 

С++

 

Если размер объекта или массива заранее неизвестен (например, изображение), или размер объекта слишком большой, чтобы создавать его внутри функции, значит настало время воспользоваться механизмом динамической памяти С++, использующую отдельную область памяти называемой кучей.

Для этого вам необходимо знать всего два оператора:

· new - выделение памяти, если выделение памяти не произошло возвращается нулевой указатель;

· delete - освобождение памяти, не во всех компиляторах после освобождения памяти указателю присваивается 0.


#include <iostream>
using namespace std;

int main() {
// создание объекта типа int со значением 45
// и сохранение его адреса в указателе obj
int* obj = new int(45);

// освободили память на которую указывал obj
cout<<"*obj="<<*obj<<endl;
delete obj;

// елементы массива нельзя инициализировать
// им задается значение по умолчанию
// в случае классов вызывается конструктор по умолчанию
int* array = new int[10];
cout<<"array:";
for(unsigned int i=0; i<10; i++)
cout<<array[i]<<" ";
cout<<endl;
delete [] array;

// для избежания возможных ошибок
// указателю лучше присвоить 0 (при доступе
// к нулевому указателю генерируется системная ошибка,
// а значит ошибка не останется незамеченной)
array=0;
...
}


Date: 2015-07-17; view: 945; Нарушение авторских прав; Помощь в написании работы --> СЮДА...



mydocx.ru - 2015-2024 year. (0.006 sec.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав - Пожаловаться на публикацию