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

Язык С
Строк программы, исключая математическое обеспечение Является учебным введением в центральную часть языка “C” Hачинаем. Единственный способ освоить новый язык Оператор FOR Набор полезных программ Подсчет символов Подсчет слов Функции Аргументы - вызов по значению Область действия: внешние переменные Резюме Константы Описания Преобразование типов До 9 и буквы от а до F Операции и выражения присваивания Старшинство и порядок вычисления Операторы и блоки Переключатель Цикл DO - WHILE Оператор CONTINUE Основные сведения Функции, возвращающие нецелые значения Еще об аргументах функций Правила, определяющие область действия Статические переменные Блочная структура Рекурсия Указатели и адреса Указатели и массивы Адресная арифметика Указатели символов и функции Указатели - не целые До 12, а не от 0 до 11. Так как за экономию памяти у нас пока не награждают, такой способ проще, чем подгонка индек-сов Инициализация массивов указателей Указатели на функции Структуры Структуры и функции Указатели на структуры Мы продемонстрируем, как правильно выполнить эту задачу Поля Определение типа Обращение к стандартной библиотеке Форматный вывод - функция PRINTF Форматный ввод - функция SCANF Форматное преобразование в памяти Обработка ошибок - STDERR и EXIT Обращение к системе Низкоуровневый ввод/вывод - операторы READ и WRITE Произвольный доступ - SEEK и LSEEK Пример - распечатка справочников Пример - распределитель памяти Константы Синтаксическая нотация Преобразования Первичные выражения Унарные операции Аддитивные операции Операция присваивания Спецификаторы типа Описание структур и объединений Инициализация TYPEDEF Оператор SWITCH Внешнее определение функции Область действия внешних идентификаторов Неявные описания Явные преобразования указателей Анахронизмы Операторы
439386
знаков
0
таблиц
0
изображений

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

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

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

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

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

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

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

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

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

 

INT A[10]

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

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

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

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


·     103 -

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). Короче, любое выражение, включающее массивы и

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

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


·     104 -

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

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

ной, так что операции 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)

·      
105 -

 

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

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

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

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

 

F(ARR)

INT ARR[];

 {

...

 }

 

или

F(ARR)

INT *ARR;

 {

...

 }

 

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

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

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

 


Информация о работе «Язык С»
Раздел: Информатика, программирование
Количество знаков с пробелами: 439386
Количество таблиц: 0
Количество изображений: 0

Похожие работы

Скачать
48443
0
0

... основаниям. При этом философская абстракция языка оказывается неразрывно связана с основными темами и движениями философии в целом. Более конкретно, на ранние стадии традиционно рассматриваемого в рамках АФ анализа обыденного языка глубокое влияние оказала философия Дж. Э. Мура, особенно его учение о здравом смысле, согласно которому такие понятия, как «человек», «мир», «я», «внешний мир», « ...

Скачать
43709
0
0

... и других странах СНГ, а также облегчение доступа к русской и мировой культуре и науке. Таким образом, судя по данным наших исследований, востребованность русского языка осталась в республике достаточно высокой. Многие представители современной молдавской молодежи продолжают, как их отцы и деды, тянуться к русской культуре, научным и техническим достижениям России. Русский язык остается языком ...

Скачать
39778
0
1

... рисуночное словесно-слоговое письмо). Памятники среднеэламского периода (14—12 вв. до н.э.) выполнены аккадской клинописью. Памятники новоэламского периода относятся к 8—6 вв. до н.э. Был официальным языком в персидском государстве Ахеменидов в 6—4 вв. предполагается, что он, подвергшись влиянию древнеперсидского, сохранился до раннего средневековья. 7. Бурушаски язык Язык бурушаски ( ...

Скачать
64931
0
0

... /диалект), скифский, согдийский, среднеперсидский, таджикский, таджриши (язык/диалект), талышский, татский, хорезмийский, хотаносакский, шугнано-рушанская группа языков, ягнобский, язгулямский и др. Они относятся к индоиранской ветви индоевропейских языков. Области распространения: Иран, Афганистан, Таджикистан, некоторые районы Ирака, Турции, Пакистана, Индии, Грузии, Российской Федерации. Общее ...

0 комментариев


Наверх