Главная Случайная страница


Полезное:

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


Категории:

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






Указатели и массивы





 

В языке "C" существует сильная взаимосвязь между указа-

телями и массивами, настолько сильная, что указатели и мас-

сивы действительно следует рассматривать одновременно. Любую

операцию, которую можно выполнить с помощью индексов масси-

ва, можно сделать и с помощью указателей. вариант с указате-

лями обычно оказывается более быстрым, но и несколько более

трудным для непосредственного понимания, по крайней мере для

начинающего. описание

 

INT A[10]

 

определяет массив размера 10, т.е. Набор из 10 последова-

тельных объектов, называемых A[0], A[1],..., A[9]. Запись

A[I] соответствует элементу массива через I позиций от нача-

ла. Если PA - указатель целого, описанный как

 

INT *PA

 

то присваивание

 

PA = &A[0]

 

приводит к тому, что PA указывает на нулевой элемент массива

A; это означает, что PA содержит адрес элемента A[0]. Теперь

присваивание

 

X = *PA

 

будет копировать содержимое A[0] в X.

Если PA указывает на некоторый определенный элемент мас-

сива A, то по определению PA+1 указывает на следующий эле-

мент, и вообще PA-I указывает на элемент, стоящий на I пози-

ций до элемента, указываемого PA, а PA+I на элемент, стоящий

на I позиций после. Таким образом, если PA указывает на

A[0], то

 

*(PA+1)

 

ссылается на содержимое A[1], PA+I - адрес A[I], а *(PA+I) -

содержимое A[I].

Эти замечания справедливы независимо от типа переменных

в массиве A. Суть определения "добавления 1 к указателю", а

также его распространения на всю арифметику указателей, сос-

тоит в том, что приращение масштабируется размером памяти,

занимаемой объектом, на который указывает указатель. Таким

образом, I в PA+I перед прибавлением умножается на размер

объектов, на которые указывает PA.

Очевидно существует очень тесное соответствие между ин-

дексацией и арифметикой указателей. в действительности ком-

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

массива. В результате этого имя массива является указатель-

ным выражением. Отсюда вытекает несколько весьма полезных

следствий. Так как имя массива является синонимом местополо-

жения его нулевого элемента, то присваивание PA=&A[0] можно

записать как

 

PA = A

 

Еще более удивительным, по крайней мере на первый взг-

ляд, кажется тот факт, что ссылку на A[I] можно записать в

виде *(A+I). При анализировании выражения A[I] в языке "C"

оно немедленно преобразуется к виду *(A+I); эти две формы

совершенно эквивалентны. Если применить операцию & к обеим

частям такого соотношения эквивалентности, то мы получим,

что &A[I] и A+I тоже идентичны: A+I - адрес I-го элемента от

начала A. С другой стороны, если PA является указателем, то

в выражениях его можно использовать с индексом: PA[I] иден-

тично *(PA+I). Короче, любое выражение, включающее массивы и

индексы, может быть записано через указатели и смещения и

наоборот, причем даже в одном и том же утверждении.

 

Имеется одно различие между именем массива и указателем,

которое необходимо иметь в виду. указатель является перемен-

ной, так что операции PA=A и PA++ имеют смысл. Но имя масси-

ва является константой, а не переменной: конструкции типа

A=PA или A++,или P=&A будут незаконными.

Когда имя массива передается функции, то на самом деле

ей передается местоположение начала этого массива. Внутри

вызванной функции такой аргумент является точно такой же пе-

ременной, как и любая другая, так что имя массива в качестве

аргумента действительно является указателем, т.е. Перемен-

ной, содержащей адрес. мы можем использовать это обстоятель-

ство для написания нового варианта функции STRLEN, вычисляю-

щей длину строки.

 

STRLEN(S) /* RETURN LENGTH OF STRING S */

CHAR *S;

{

INT N;

 

FOR (N = 0; *S!= '\0'; S++)

N++;

RETURN(N);

}

 

Операция увеличения S совершенно законна, поскольку эта

переменная является указателем; S++ никак не влияет на сим-

вольную строку в обратившейся к STRLEN функции, а только

увеличивает локальную для функции STRLEN копию адреса. Опи-

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

 

CHAR S[];

CHAR *S;

 

совершенно эквивалентны; какой вид описания следует предпо-

честь, определяется в значительной степени тем, какие выра-


жения будут использованы при написании функции. Если функции

передается имя массива, то в зависимости от того, что удоб-

нее, можно полагать, что функция оперирует либо с массивом,

либо с указателем, и действовать далее соответвующим обра-

зом. Можно даже использовать оба вида операций, если это ка-

жется уместным и ясным.

Можно передать функции часть массива, если задать в ка-

честве аргумента указатель начала подмассива. Например, если

A - массив, то как

 

F(&A[2])

 

как и

 

F(A+2)

 

передают функции F адрес элемента A[2], потому что и &A[2],

и A+2 являются указательными выражениями, ссылающимися на

третий элемент A. внутри функции F описания аргументов могут

присутствовать в виде:

 

F(ARR)

INT ARR[];

{

...

}

 

или

 

F(ARR)

INT *ARR;

{

...

}

 

Что касается функции F, то тот факт, что ее аргумент в дейс-

твительности ссылается к части большего массива,не имеет для

нее никаких последствий.

 

 







Date: 2015-09-17; view: 360; Нарушение авторских прав



mydocx.ru - 2015-2024 year. (0.009 sec.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав - Пожаловаться на публикацию