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

4.1.4Работа с массивами.

Приведем в качестве примера работы с массивами фрагменты программы нахождения суммы и максимального элемента массива a из n чисел (блок-схемы соответствующих алгоритмов были приведены в 1.2.4.

#define MAX_SIZE 100 //Определение именованной константы

float a[MAX_SIZE];

float s,max;

int i,n;

············ // Ввод n и массива a из n чисел, n должно быть ············ // не больше MAX_SIZE

s=0; // Сумма элементов массива a

max=a[1]; // Максимальный элемент массива

for (i=1;i<n;i++) // Для каждого элемента

{ s+=a[i]; // Увеличение суммы на a[i]

if (a[i]>max) // Если элемент больше максимального, то

max=a[i]; // он становится максимальным

}

············ // Вывод n, массива a, s и max

4.2Указатели.

4.2.1Адреса и указатели.

Напомним, что память ЭВМ представляет собой последовательность пронумерованных ячеек, каждая из которых имеет свой адрес. Там хранятся как команды программы, так и данные, ею используемые. Данные типа char в языке Си занимают один байт, данные целого типа - обычно два байта, а вещественного - 4 байта.

Если рассмотреть операцию a=5, то для компилятора это означает: занести число 5 по адресу переменной с именем a, т.е. в ячейку с адресом 2008 (см.таблицу).

Имя

ptr

a

d

Адрес

2000

2004

2008

2012

Значение

2012

5

32

В Си есть возможность работать непосредственно с адресами без использования имени переменной. Для этого предусмотрены специальные переменные (занимающие обычно 2 или 4 байта), называемые указателями (pointer). В указателе хранится адрес объекта какого-либо типа. Описание указателя имеет вид (синтаксис):

тип_объекта *имя_указателя ;

Это означает, что в этом указателе будет храниться адрес какого-либо объекта (например, переменной) указанного типа. Например,

int *ptr, d;

означает, что в указателе ptr будет храниться адрес переменной целого типа, а в переменной d - значение целого типа.

Занести в указатель адрес можно, используя специальную операцию адресации: &имя_переменной , например, ptr=&d означает: занести в указатель ptr адрес переменной d. Говорят, что ptr указывает (или ссылается) на d.

Чтобы изменить значение переменной, используя ее указатель (т.е. значение по указанному адресу), нужно вместо имени этой переменной в левой части оператора присваивания использовать имя указателя на эту переменную со знаком * перед ним. Например, операторы *ptr=32; и d=32; равнозначны, если ptr ссылается на d.

Операцию * называют операцией раскрытия ссылки, она означает переменную, на которую ссылается указатель. Выражение *указа­тель может использоваться вместо имени соответствующей переменной в любых выражениях Си (в нашем случае *ptr вместо d). Унарные операции & и * имеют тот же приоритет, что и унарный минус (см. таблицу в 2.5.3.5).

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

Пусть описаны целые массив a, переменная s и указатель на целое p.

int *p,a[5]={7,-3,8,-2,4},s;

В языке Си имя массива (например, a) означает на самом деле адрес его нулевого элемента, т.е. адрес ячейки a[0]. Поэтому операторы

p=&a[0]; и p=a;

эквивалентны и предписывают занести в p адрес нулевого элемента массива a (т.е. 2004). Оператор s=*p; копирует в s содержимое a[0].

Имя

p

a[0]

a[1]

a[2]

a[3]

a[4]

s

Адрес

2000

2004

2006

2008

2010

2012

2014

Значение

2004

7

-3

8

-2

4

7

Если p указывает на нулевой элемент массива a, то по определению p+1 указывает на следующий элемент, т.е. на a[1], а значением выражения *(p+1) является значение этого элемента, т.е. -3. Аналогично p+i (также, как и a+i) указывает на i -й элемент массива a, следовательно значения выражений a[i] , p[i], *(a+i) и *(p+i) равны.

Отличием в использовании имени массива и указателя на массив является то, что указатель - это переменная и в нее можно занести в дальнейшем какой-либо другой адрес, например, записать p++ (тогда в p будет находиться адрес 2006. С именем массива такое сделать нельзя, т.к. адрес массива определен компилятором раз и навсегда.