рефераты рефераты
Главная страница > Курсовая работа: Массивы. Двумерные массивы  
Курсовая работа: Массивы. Двумерные массивы
Главная страница
Банковское дело
Безопасность жизнедеятельности
Биология
Биржевое дело
Ботаника и сельское хоз-во
Бухгалтерский учет и аудит
География экономическая география
Геодезия
Геология
Госслужба
Гражданский процесс
Гражданское право
Иностранные языки лингвистика
Искусство
Историческая личность
История
История государства и права
История отечественного государства и права
История политичиских учений
История техники
История экономических учений
Биографии
Биология и химия
Издательское дело и полиграфия
Исторические личности
Краткое содержание произведений
Новейшая история политология
Остальные рефераты
Промышленность производство
психология педагогика
Коммуникации связь цифровые приборы и радиоэлектроника
Краеведение и этнография
Кулинария и продукты питания
Культура и искусство
Литература
Маркетинг реклама и торговля
Математика
Медицина
Реклама
Физика
Финансы
Химия
Экономическая теория
Юриспруденция
Юридическая наука
Компьютерные науки
Финансовые науки
Управленческие науки
Информатика программирование
Экономика
Архитектура
Банковское дело
Биржевое дело
Бухгалтерский учет и аудит
Валютные отношения
География
Кредитование
Инвестиции
Информатика
Кибернетика
Косметология
Наука и техника
Маркетинг
Культура и искусство
Менеджмент
Металлургия
Налогообложение
Предпринимательство
Радиоэлектроника
Страхование
Строительство
Схемотехника
Таможенная система
Сочинения по литературе и русскому языку
Теория организация
Теплотехника
Туризм
Управление
Форма поиска
Авторизация




 
Статистика
рефераты
Последние новости

Курсовая работа: Массивы. Двумерные массивы

Размещение трехмерного массива происходит аналогично и объявление float arr3[3][4][5] порождает в программе кроме самого трехмерного массива из шестидесяти чисел типа float массив из четырех указателей на тип float, массив из трех указателей на массив указателей на float, и указатель на массив массивов указателей на float.

При размещении элементов многомерных массивов они располагаются в памяти подряд по строкам, т.е. быстрее всего изменяется последний индекс, а медленнее - первый. Такой порядок дает возможность обращаться к любому элементу многомерного массива, используя адрес его начального элемента и только одно индексное выражение.

Например, обращение к элементу arr2[1][2] можно осуществить с помощью указателя ptr2, объявленного в форме int *ptr2=arr2[0] как обращение ptr2[1*4+2] (здесь 1 и 2 это индексы используемого элемента, а 4 это число элементов в строке) или как ptr2[6]. Заметим, что внешне похожее обращение arr2[6] выполнить невозможно так как указателя с индексом 6 не существует.

Для обращения к элементу arr3[2][3][4] из трехмерного массива тоже можнo использовать указатель, описанный как float *ptr3=arr3[0][0] с одним индексным выражением в форме ptr3[3*2+4*3+4] или ptr3[22].

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

 struct INDEX { int i,

 int j,

 int k } min_index ;

 struct INDEX * find_min (int *ptr1, int l, int m int n)

 { int min, i, j, k, ind;

 min=*ptr1;

 min_index.i=min_index.j=min_index.k=0;

 for (i=0; i*(ptr1+ind)

 { min=*(ptr1+ind);

 min_index.i=i;

 min_index.j=j;

 min_index.k=k;

 }

 }

 return &min_index;

 }

 Операции с указателями

Над указателями можно выполнять унарные операции:инкремент и декремент. При выполнении операций ++ и -- значение указателя увеличивается или уменьшается на длину типа, на который ссылается используемый указатель.

Пример:

 int *ptr, a[10];

ptr=&a[5];

 ptr++; /* равно адресу элемента a[6] */

 ptr--; /* равно адресу элемента a[5] */

В бинарных операциях сложения и вычитания могут участвовать указатель и величина типа int. При этом результатом операции будет указатель на исходный тип, а его значение будет на указанное число элементов больше или меньше исходного.

Пример:

 int *ptr1, *ptr2, a[10];

 int i=2;

 ptr1=a+(i+4); /* равно адресу элемента a[6] */

 ptr2=ptr1-i; /* равно адресу элемента a[4] */

В операции вычитания могут участвовать два указателя на один и тот же тип. Результат такой операции имеет тип int и равен числу элементов исходного типа между уменьшаемым и вычитаемым, причем если первый адрес младше, то результат имеет отрицательное значение.

Пример:

 int *ptr1, *ptr2, a[10];

 int i;

 ptr1=a+4;

 ptr2=a+9;

 i=ptr1-ptr2; /* равно 5 */

 i=ptr2-ptr1; /* равно -5 */

Значения двух указателей на одинаковые типы можно сравнивать в операциях ==, !=, <, <=, >, >= при этом значения указателей рассматриваются просто как целые числа, а результат сравнения равен 0 (ложь) или 1 (истина).

Пример:

 int *ptr1, *ptr2, a[10];

 ptr1=a+5;

 ptr2=a+7;

 if (prt1>ptr2) a[3]=4;

В данном примере значение ptr1 меньше значения ptr2 и поэтому оператор a[3]=4 не будет выполнен.

 Массивы указателей

В языке СИ элементы массивов могут иметь любой тип, и, в частности, могут быть указателями на любой тип. Рассмотрим несколько примеров с использованием указателей.

Следующие объявления переменных

 int a[]={10,11,12,13,14,};

 int *p[]={a, a+1, a+2, a+2, a+3, a+4};

 int **pp=p;

порождают программные объекты, представленные на схеме

pp     pа    .        .        .        .        .

в в    в в в

 18

aа      11 12 13    14 15

Схема размещения переменных при объявлении.

При выполнении операции pp-p получим нулевое значение, так как ссылки pp и p равны и указывают на начальный элемент массива указателей, связанного с указателем p ( на элемент p[0]).

После выполнения операции pp+=2 схема изменится и примет вид, изображенный                   

 pp pа .      .        .        .

 в в в в в

 aа     10 11 12 13 14

Схема размещения переменных после выполнения операции pp+=2.

Результатом выполнения вычитания pp-p будет 2, так как значение pp есть адрес третьего элемента массива p. Ссылка *pp-a тоже дает значение 2, так как обращение *pp есть адрес третьего элемента массива a, а обращение a есть адрес начального элемента массива a. При обращении с помощью ссылки **pp получим 12 - это значение третьего элемента массива a. Ссылка *pp++ даст значение четвертого элемента массива p т.е. адрес четвертого элемента массива.

Если считать, что pp=p, то обращение *++pp это значение первого элемента массива a (т.е. значение 11), операция ++*pp изменит содержимое указателя p[0], таким образом, что он станет равным значению адреса элемента a[1].

Сложные обращения раскрываются изнутри. Например обращение *(++(*pp)) можно разбить на следующие действия: *pp дает значение начального элемента массива p[0], далее это значение инкременируется ++(*p) в результате чего указатель p[0] станет равен значению адреса элемента a[1], и последнее действие это выборка значения по полученному адресу, т.е. значение 11.

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

 int a[3][3]={ { 11,12,13 },

 { 21,22,23 },

 { 31,32,33 } };

 int *pa[3]={ a,a[1],a[2] };

 int *p=a[0];

Схема размещения указателей на двумерный массив.

Согласно этой схеме доступ к элементу a[0][0] получить по указателям a, p, pa при помощи следующих ссылок: a[0][0], *a, **a[0], *p, **pa, *p[0].

Рассмотрим теперь пример с использованием строк символов. Объявления переменных можно изобразить схемой представленной:

 char *c[]={ "abs", "d", "yes", "no" };

 char **cp[]={ c+3, c+2 , c+1 , c };

 char ***cpp=cp;

Схема размещения указателей на строки.

Динамическое размещение массивов

При динамическом распределении памяти для массивов следует описать соответствующий указатель и присваивать ему значение при помощи функции calloc. Одномерный массив a[10] из элементов типа float можно создать следующим образом

 float *a;

 a=(float*)(calloc(10,sizeof(float));

Для создания двумерного массива вначале нужно распределить память для массива указателей на одномерные массивы, а затем распределять память для одномерных массивов. Пусть, например, требуется создать массив a[n][m], это можно сделать при помощи следующего фрагмента программы:

 #include

 main ()

 { double **a;

 int n,m,i;

 scanf("%d %d",&n,&m);

 a=(double **)calloc(m,sizeof(double *));

 for (i=0; i<=m; i++)

 a[i]=(double *)calloc(n,sizeof(double));

 . . . . . . . . . . . .

 }

Аналогичным образом можно распределить память и для трехмерного массива размером n,m,l. Следует только помнить, что ненужную для дальнейшего выполнения программы память следует освобождать при помощи функции free.

 #include

 main ()

 { long ***a;

 int n,m,l,i,j;

 scanf("%d %d %d",&n,&m,&l);

 /* -------- распределение памяти -------- */

 a=(long ***)calloc(m,sizeof(long **));

 for (i=0; i<=m; i++)

 { a[i]=(long **)calloc(n,sizeof(long *));

 for (j=0; i<=l; j++)

 a[i][j]=(long *)calloc(l,sizeof(long));

 }

 . . . . . . . . . . . .

 /* --------- освобождение памяти ----------*/

 for (i=0; i<=m; i++)

 { for (j=0; j<=l; j++)

 free (a[i][j]);

 free (a[i]);

 }

 

free (a);

 }

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

 Пример:

 #include

 main()

 { int vvod(double ***, long **);

 double **a; /* указатель для массива a[n][m] */

 long *b; /* указатель для массива b[n] */

 vvod (&a,&b);

 .. /* в функцию vvod передаются адреса указателей, */

Страницы: 1, 2, 3, 4, 5, 6, 7, 8

рефераты
Новости