Лекции.Орг


Поиск:




Категории:

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

 

 

 

 


Операция * соответствует словам «значение, расположенное по указанному адресу».

Лабораторная работа № 14

«Массивы и указатели. Многомерные массивы»

 

Цель работы: Изучить одномерные и двумерные массивы, уметь объявлять одномерные и двумерные массивы в программе, обращаться к элементу массива, работать с индексными переменными.

.

Теоретические сведения

Массивом называется набор данных одного и того же типа, собранных под одним именем. Каждый элемент массива определяется именем массива и порядковым номером элемента, который называется индексом. Индекс всегда является целым числом.

Основная форма объявления массива в программе:

 

Тип < имя массива > [размер 1] [размер 2]….[размер n];

 

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

Тип <имя массива> [размер];

Тип – базовый тип элементов (int, float, char).

Размер – количество элементов одномерного массива.

В языке Си индекс всегда начинается с 0. Первый элемент - массива всегда имеет индекс 0. Например, если мы объявили массив int a [100], это значит массив содержит 100 элементов – от a [0] до a [99]. Для одномерного массива легко подсчитать, сколько байт в памяти будет занимать этот массив.

N Килобайт = < размер базового типа > * < количество элементов >.

Язык Си допускает двумерные массивы. Их можно назвать как: массив одномерных массивов. Двумерный массив int a[3][4] можно представить в виде таблички:

  Hoмер столбца – второй индекс (j)
Номер строки – первый индекс (i) A [0] [0] A [0] [1] A [0] [2] A [0] [3]
A [1] [0] A [1] [1] A [1] [2] A [1] [3]
A [2] [0] A [2] [1] A [2] [2] A [2] [3]

 

В памяти ЭВМ массив располагается непрерывно по строкам, т. е.

a [0] [0], a [0] [1], ……. a [0] [3], a [1] [0], a [1] [1], …..a [2] [3].

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

Инициализацию массивов можно производить разными способами.

Первый способ.

float arr [6] = {1.1, 2.2, 3.3, 4.0, 5.0, 6}; // одномерный массив

int a [3] [5] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}

Второй способ.

a[0] [0] = 1; a [0] [1] = 2; a [0] [2] = 3; a [0] [3] = 4

a [0] [4] = 5; a [0] [5] = 6; a [0] [6] = 7; a [0] [7] = 8 и т. д.

Многомерные массивы, в том числе и двумерные, можно инициализировать, рассматривая их как массив массивов.

Инициализации:

int a [3] [5] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; и

int a [3] [5] = {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}, {11, 12, 13, 14, 15}};

эквиваленты. Количество инициализаторов не обязательно должно совпадать с количеством элементов массива. Если инициализаторов меньше, то оставшиеся элементы массива не определены.

В тоже время инициализации:

int a [3] [5] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; и

int a [3] [5] = {{1, 2, 3}, {4, 5, 6, 7, 8}, {9, 10, 11}};

различны.

Соответствующие массивы будут заполнены следующим образом:

В первом случае:

         
         
         

Во втором случае:

         
         
         

 

В пустых клетках значения не определяются.

Символьные массивы могут инициализироваться как обычные массивы

char str [15] = {‘B’, ‘o’, ‘r’, ‘l’, ‘a’, ‘n’, ‘d’, ‘ ‘, ‘C’, ‘+’, ‘+’};

а могут как строка:

сhаr str [15] = ‘Borland C + +’;

Можно указывать массив без указания размера:

int mas [ ] = {1, 2, 3, 4, 5, 1, 2};

char str [ ] = ”Это объявление и инициализация символов”;

компилятор сам определит количество элементов массива. Символьные массивы в языке Си занимают особое место. Во многих языках есть специальный тип – строка символов. В языке Си этого нет, и работа со строками реализована как работа с одномерным массивом.

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

Указатель объявляется следующим образом:

тип *<имя переменной>;

Например:

char *ch;

int * temp, i, *j;

float * pf, f;

Здесь объявлены указатели ch, temp, j, pf, переменная i – целого типа и переменная f типа float.

Операции над указателями. С указателями связаны две специальные операции & и *. Обе эти операции являются унарными, т. е. они имеют один операнд, перед которыми они ставятся.

Операция & соответствует операции «взять адрес».

Операция * соответствует словам «значение, расположенное по указанному адресу».

В указателе очень важным является базовый тип, т.к. он определяет, сколько байтов занимает переменная указатель. Если int – 2 байта, char – один байт и т.д. Простейшие действия с указателями продемонстрируем на следующей программе.

Пример

 

# include <stdio.h>

main ()

{

float x = 10.1, y;

float * pf;

pf = &x;

y = *pf;

printf(“x = %f y= %f”, x, y); // Результат: x=10.1; y=10.1; pf=FFF6

*pf ++;

printf (“x = %f y = %f”, x, y); // Результат: x=10.1; y=10.1; pf=FFF2

y =1+ *pf * y;

printf (“x = %f y = %f”, x, y); // Результат: x=10.1; y=1; pf=FFF6

return 0;

}

К указателям можно применить операцию присваивания. Указатели одного и того же типа могут использоваться в операции присваивания, как любые другие переменные.

Пример

# include <stdio.h>

main ()

{

int x = 0;

int *p, *g;

p = &x;

g = p;

printf(“%p”, p); /* печать содержимого p */

printf(“%p”, g); /* печать содержимого g */

printf(“%d %d”, x., *g); / *печать величины х и величины по адресу g */

}

В этом примере приведена еще одна спецификация формата функции printf() %p – печать адреса памяти в шестнадцатеричной системе счисления.

В языке Си указателю допустимо присвоить любой адрес памяти. Однако если объявлен указатель на целое int *pi; а по адресу, который присвоен данному указателю, находится переменная типа float, то при компиляции будет выдано сообщение об ошибке в строке

p = &x;

Эту ошибку можно исправить, преобразовав указатель на int к типу указателя на float явным преобразованием типа:

p = (int*)&x;

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

Массивы описывают регулярную структуру данных одного типа.

Одномерные массивы:

int temp [365];

char arr [10];

char *point[10];

Двумерные массивы:

int array[4] [10];

char arr [3] [7];

Число в [ ] указывает количество элементов массива, поэтому:

temp [365] – массив из 365 элементов.

Доступ к каждому элементу осуществляется по его индексу (номеру), т.е. temp[0], temp[1],…,temp[364]- последний элемент. Элементы массива нумеруются начиная с 0.

Можно также использовать многомерные массивы, например: int arr [k] [l] …[n];

Однако следует помнить, что для хранения элементов таких массивов требуется значительный объем памяти.

Рассмотрим, как происходит размещение элементов массива в памяти ЭВМ. Как правило, элементы массива занимают последовательные ячейки памяти. При этом элементы размещаются таким образом, что самый последний индекс возрастает быстрее. Это в случае двумерного массива означает, что он будет записываться построчно: строка за строкой. Поскольку указатели указывают адрес ячейки, то между массивами и указателями существует тесная связь. Вспомним, что имя массива – это указатель на его первый элемент. По существу массив можно рассматривать как индексированный указатель. Доступ к элементам массива осуществляется по номеру индекса. При этом приращение индекса на единицу вызывает перемещение указателя на число байт, соответствующее объекту данного типа: для целых чисел на 2 байта, для действительных - на 4 байта и т.д.

Объявления int mas[] и int *mas идентичны по действию: оба объявляют mas указателем.

Индекс массива действует аналогично стрелки часов, показывающей по очереди на каждый следующий элемент массива.

Пример

int mas[10];

int *ptr;

ptr = mas; // присваивает адрес указателю

// следующие операции дадут один и тот же результат:

mas[2] = 20;

*(ptr + 2) = 20;

// следующая операция прибавит 2 к первому элементу:

*ptr + 2;

 

Указатели и многомерные массивы. Рассмотрим двумерный массив и действия с указателями.

int mas[4][2];

int *ptr;

ptr = mas;

ptr сейчас указывает на первый столбец первой строки, т.е.

ptr = = mas = = &mas [0] [0];

Увеличим указатель:

ptr+1 = = &mas [0] [1];

ptr+2 = = &mas [1] [0];

ptr+3 = = &mas [1] [1] и т.д.

Двумерный массив можно представить как массив массивов. В нашем случае мы имеем четырех элементный массив, состоящий из двух элементов. Примечательно, что этот четырех элементный массив можно представить в виде одномерного mas[0],…,mas[3]. При этом имя массива по-прежнему является указателем на его первый элемент, т.е. mas[0]= =&mas[0] [0]. На что же будут указывать mas[i]? В этом случае mas [i] указывает на i-тую строку, т.е. на первый элемент i - й строки. Таким образом

mas [0] == &mas [0] [0];

mas [1] == &mas [1] [0];

mas[2] == &mas [2] [0];

mas[3] == &mas [3] [0];



<== предыдущая лекция | следующая лекция ==>
Имя_записи variable; // объявление переменной типа запись | Эмбриональное развитие животных (прочесть текст конспекта).
Поделиться с друзьями:


Дата добавления: 2016-12-29; Мы поможем в написании ваших работ!; просмотров: 333 | Нарушение авторских прав


Поиск на сайте:

Лучшие изречения:

Лаской почти всегда добьешься больше, чем грубой силой. © Неизвестно
==> читать все изречения...

2392 - | 2261 -


© 2015-2024 lektsii.org - Контакты - Последнее добавление

Ген: 0.14 с.