Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции программирование.doc
Скачиваний:
41
Добавлен:
05.11.2018
Размер:
4.73 Mб
Скачать

Описатель имя[разм_1] …[разм_i]… [разм_n];

где описатель – ключевое слово, определяющее тип элементов массива;

имя – идентификатор массива (формируется аналогично имени переменной);

размер – целая константа, определяющая количество элементов массива;

i - номер измерения (i=1 – первое измерение, i=2 – второе имзерение и т.д.);

n - измерение массива;

разм_i - целая константа, определяющая количество элементов массива по i-му измерению;

[ ] – ограничители размера массива по каждому измерению.

Константное выражение разм_i может быть опущено в случаях:

  1. при обявлении массив инициализируется;

  2. массив объявлен как формальный параметр;

  3. массив обявлен как ссылка на массив, явно определённый в другом файле.

Инициализация одномерного массива

float[3]={1.,3.5,4.1}; или float[]={1.,3.5,4.1};

Инициализация многомерного массива

float[2][3]={{1.,3.5,4.1},{1.,3.5,4.1}}; или float[][]={{1.,3.5,4.1},{1.,3.5,4.1}};

Обозначение элементов многомерного массива.

Индексированная переменная (индексное выражение) – обозначение ячейки для хранения каждого элемента массива.

Структура обозначения индексированной переменной многомерного массива:

имя[индекс _1]…[ индекс _i]…[индекс_n];

имя – индетификатор массива;

индекс_i - целая константа, определяющая номер элемента по i-му измерению;

[ ] – ограничители размера массива по каждому измерению.

Методика хранения многомерных массивов позволяет рассчитывать адрес каждого элемента через начальный адрес массива путём прибавления к нему значения смещения текущего элемента относительно первого

а = а1+ смещение

При этом а1-адрес первого элемента.

Для двухмерного массива смещение определяется по формуле

смещение = индекс_1*разм_2+индекс_2

Для трёхмерного массива смещение определяется по формуле

смещение = индекс_1*(разм_2*разм_3+индекс_2*разм_3+индекс_3

Указатели и адресная арифметика

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

Применение указателей необходимо или полезно в следующих ситуациях:

  • при динамическом распределении памяти;

  • при работе с файлами;

  • передача указателей в качестве параметров функции позволяет вызываемой функции изменять данные вызывающей функции;

  • указатель является альтернативным (по отношению к индексам) способом работы с массивом и позволяет обеспечить передачу массива для обработки вызываемой функции;

  • можно определить указатель на функцию и использовать этот указатель для вызова функции. Это даёт возможность передавать функции в функции.

Структура описания указателя

описатель иу1[,*иу2,…,*иуN];

описатель – ключевое слово, определяющая тип указателя ( тип объекта, на который он ссылается);

иу1, …,иуNидентификаторы указателей;

* - признак указателя при описании.

Соответствие указателя и адреса переменной, на которую он ссылается , выражается зависимостью

иу=&ип;

иу – идентификатор указателя

& - операция взятия адреса

ип – идентификатор переменной

Указатель позволяет не только хранить адреса переменных, но и вызывать в случае необходиомсти их содержимое с помошью операции разадресации (*).

Разадресация указателя предписывает получение содержимого переменной (ячейки оперативной памяти), на которую он ссылается.

Запись разадресации имеет вид

*иу

Присваивание указателей

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

int i=12535,*p1,*p2;

pi1=&i;

p2=p1;

print(“%d\n”,i);

print(“%d\n”,*p1);

print(“%d\n”,*p2);

Использование указателей в арифметических операциях.

С указателями могут быть использованы только операции (++), (--), сложение и вычитания.

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

Указатель может быть элементом в операциях сложения и вычитания вторым операндом операции должна быть целочисленная константа. Содержимое указателя увеличивается или уменьшается на значение, равное произведению константы на размер объекта, который они адресуют.

Связь массивов и указателей

Между массивами и указателями существует прямая связь. Когда объявляется массив, например

int arr[25];

то этим объявляется несколько больше, чем только выделения памяти для двадцати пяти элементов типа int.А именно, идентификатор массива arr определяется как константный указатель на первый элемент массива (адрес первого элемента массива &arr[0]).

Так как идентификатор массива определяется как адрес. то следующее присваивание является допустимым

int arr[25];

int *ptr;

ptr=arr;

последний оператор можно записать в эквивалентной форме

ptr=&arr[0];

Для доступа к элементам массива тоже существуют два способа

Первый способ доступа к элементам массива связан с использованием обычных индексных выражений вида arr[i].

Второй способ связан с использованием адресного выражения (или выражения с указателем на массив)

*(ptr+i)

В общем случае индексное выражение в языке Си имеет вид:

выражение_1[выражение_2]

где выражение_1 – это любой указатель, например, идентификатор массив, а выражение_2 – это целая величина. Однако требуется только, чтобы одно из выражений было указателем, а второе целой величиной. Поэтому выражение_1 может быть целой величиной, а выражение_2 – указателем.

Рассмотрим, как вычисляется индексное выражение arr[5]. Идентификатор arr является указателем начала массива. В соответствии с правилами выполнения операции сложения указателя с целой величиной целая величина преобразуется к адресному представлению путём умножения её на размер типа, адресуемого указателем. Целая константа 5 умножается на размер типа int преобразованное значение числа 5 представляет 5 позиций типа int. Это преобразованное значение числа 5 складывается со значением указателя arr , то даёт адрес, относящийся к шестой ( т.к. нумерация идёт с нулевого индекса) позиции типа int после arr. К полученному результату применяется операция “разадресация”. Результатом является значение шестого элемента массива. В терминах языка Си это выглядит так:

arr[5]=*(arr+5)=*(arr+5*syzeof(int))

Следовательно следующие выражения ссылаются на шестой элемент массива arr.

arr[5]

5[arr]

*(arr+5)

*(5+arr)

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

ptr[5]

5[pt]

ссылаются на тот же шестой элемент массива arr. Если расписать индексное выражение ptr[5], то получится адресное выражение

*(ptr+5)

Операции с указателями на массивы.

Если два указателя ptr1 и ptr2 ссылаются на один и тот же массив

int arr[SIZE]

int *ptr1, *ptr2;

int i;

ptr1=ptr2=arr;

то к ним можно применить операции, перечисленные ниже

Операция

Результат операции

ptr1++

ptr1--

Устанавливает ptr1 на следующий (предыдущий) элемент массива аrr

ptr1+i

ptr1-i

Устанавливает ptr1 на i-й элемент после (перед) ptr1

ptr2- ptr1

Даёт число элементов между ptr1 и ptr2 (отрицательное, если ptr2 указывает на элемент с меньшим индексом)

ptr1 == ptr2

Результат «истина» (1), если ptr1 и ptr2 указывают на один и тот же элемент массива. В противном случае – “ложь” (0)

ptr1 != ptr2

Результат «истина» (1), если ptr1 и ptr2 указывают на разные элементы массива. В противном случае – “ложь” (0)

ptr1 < ptr2

ptr1 <= ptr2

Результат «истина» (1), если ptr1 указывает на элемент массива с меньшим (или равным) индексом, чем ptr2. В противном случае – “ложь” (-0)

ptr1> ptr2

ptr1 >= ptr2

Результат «истина» (1), если ptr1 указывает на элемент массива с большим (или равным) индексом, чем ptr2. В противном случае – “ложь” (-0)

Указатели на многомерные массивы.

Многомерный массив в языке Си – это массив массиов, т.е. массив, элементами котрого являются массивы. Например трехмерный массив есть масив, элементы которого двухмерные массивы

arr[L][M][N];

Массив arr состоит из L элементов. Каждый элемент – это двухмерный массив размерностью M на N.

Рассмотрим, как осуществлять доступ к элементм многомерного массива через указатель. Сделаем это на примере массива arr.

Объявим указатель и свяжем его с массивом arr

int *ptr;

ptr=arr[0][0][0];

arr[i][j][k], или к k-му элементу j-й строки i-го массива M на N массива arr. Последовательно это выполняется так

адрес первого массива M на N ptr

в массиве arr

адрес i-го массива M на N ptr + i*(M*N)

в массиве arr

адрес j-й строки i-го массива M на N ptr + i*(M*N) +j*N

в массиве arr

адрес k-го элемента j-й строки i-го массива ptr + i*(M*N) +j*N+k

M на N ptr + i*(M*N) +j*N в массиве arr

k-й элемент j-й строки i-го массива *(ptr + i*(M*N) +j*N+k)

M на N ptr + i*(M*N) +j*N в массиве arr

Рассмотрим программирование арифметических циклов с табличным изменением аргумента на конкретном примере задачи о вознаграждениях.