Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
119
Добавлен:
13.03.2016
Размер:
470.02 Кб
Скачать

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

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

Имя одномерного массива является указателем-константой, равной адресу начала массива, т. е. адресу элемента с индексом 0 (первого элемента).

Рассмотрим объявление некоторого одномерного массива, для определенности int a[10]; тогда обозначение&a[0] эквивалентноa, a[0]эквивалентно *a, &a[i] эквивалентно a+i (i=0,1,...9), a[i] эквивалентно*(a+i).

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

Имя двумерного массива является указателем-константойна начало (элемент с индексом 0)массива указателей-констант,i-й элемент этого массива - указатель -константа на начало (элемент с индексом 0)i-й строки двумерного массива.

Так, например, с массивом int b[5][8] связан массив указателей-константb[0], b[1],...,b[4]; b[ i ] - указатель на началоi-й строки, т. е. на элементb[ i ][0], i=0,1,...,4;вышесказанное поясняется схемой:

b

b[0]

b[0][0]

b[0][1]

. . .

b[0][7]

b[1]

b[1][0]

b[1][1]

. . .

b[1][7]

b[2]

b[2][0]

b[2][1]

. . .

b[2][7]

b[3]

b[3][0]

b[3][1]

. . .

b[3][7]

b[4]

b[4][0]

b[4][1]

. . .

b[4][7]

Элемент массива b[i][j] можно также обозначить*(b[i]+j) или*(*(b+i)+j); это все равноправные обозначения.&b[i][j], b[i]+j, *(b+i)+j - также равноправные обозначения адреса элемента массиваb[i][j].

Для любого из трех обозначений элемента двумерного массива программа в кодах получается практически одинаковой по производительности, хотя при использовании арифметики указателей вместо квадратных скобок несколько более короткой [3].Хороший стиль программирования предполагает употребление в пределах одной программы одного (из трех) обозначений.

Часть. Функции и многофайловые программы в Си

2.1. Общие сведения о подпрограммах и функциях

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

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

Главным вопросом, который следует решить при проектировании подпрограмм, является вопрос о способе передачи данных между подпрограммой и программой. В любом алгоритмическом языке существует два основных способа передачи данных:через список параметров подпрограммыичерез глобальные переменные(общие области, внешние имена). Первый способ дает возможность подстановки, т. е. передачи в подпрограмму при каждом обращении к ней нового параметра. В список параметров подпрограммы включаются переменные, значения которых должны быть переданы из программы в подпрограмму и из подпрограммы в программу (т.е. "исходные" и "выходные"11переменные для подпрограммы).

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

Существует два способа замены формальных параметров на фактические:" по имени"13(call-by-reference) и "по значению" (call-by-value). Передача параметра "по имени" означает передачу в подпрограмму адреса фактического параметра. При этом любое изменение формального параметра внутри подпрограммы есть изменение соответствующего фактического параметра. Поэтому константы и выражения нельзя передавать "по имени" - они могут измениться. Передача параметров "по значению" означает пересылку значения фактического параметра в ячейку, соответствующую формальному параметру, при обращении к подпрограмме. Это обеспечивает сохранность величины фактического параметра. Изменение формального параметра внутри подпрограммы никак не отражается на фактическом. "По значению" нельзя передавать переменные-результаты подпрограммы; их следует передавать "по имени". Если фактическое значение может быть константой или выражением, то следует использовать замену "по значению".

Заметим, что при передаче "по имени", как правило, экономится память, так как формальные параметры не копируют фактические; поэтому массивы обычно передаются "по имени". При передаче "по значению" обычно экономится время работы подпрограммы (за счет отсутствия переадресации при обращении к формальным параметрам).

В большинстве алгоритмических языков имеется два вида подпрограмм: подпрограммы общего назначения (они часто называются процедурами) и функции. Функции следует использовать, если подпрограмма имеет одно выходное значение; классическими примерами функций во всех алгоритмических языках являются стандартные математические функции: синус, косинус, абсолютная величина и т. д. Имя функции является не только именем ее алгоритма, но и именем результата; это имя можно использовать в выражениях (как sin, cos, abs, и т. д.) Говорят, что функция через свое имя возвращает единственный (или основной) результат.

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