Главная » Просмотр файлов » Керниган и Ритчи - Язык программирования Си

Керниган и Ритчи - Язык программирования Си (793773), страница 26

Файл №793773 Керниган и Ритчи - Язык программирования Си (Керниган и Ритчи - Язык программирования Си) 26 страницаКерниган и Ритчи - Язык программирования Си (793773) страница 262019-04-24СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 26)

Поскольку имя массива является синонимом расположения егоначального элемента, присваивание ра=&а[0] можно также записать в следующем виде:pa = a;Еще более удивительно (по крайней мере на первый взгляд) то, что а[i] можно записать как *(а+i).Вычисляя а[i], Си сразу преобразует его в *(a+i); указанные две формы записи эквивалентны. Из этогоследует, что полученные в результате применения оператора & записи &а[i] и a+i также будутэквивалентными, т. е.

и в том и в другом случае это адрес 1-го элемента после а. С другой стороны, если ра —указатель, то его можно использовать с индексом, т. е. запись pa[i] эквивалентна записи *(pa+i). Корочеговоря, элемент массива можно изображать как в виде указателя со смещением, так и в виде имени массивас индексом.Между именем массива и указателем, выступающим в роли имени массива, существует одно различие.Указатель — это переменная, поэтому можно написать ра=а или ра++. Но имя массива не являетсяпеременной, и записи вроде а=ра или а++ не допускаются.Если имя массива передается функции, то последняя получает в качестве аргумента адрес его начальногоэлемента. Внутри вызываемой функции этот аргумент является локальной переменной, содержащей адрес.Мы можем воспользоваться отмеченным фактом и написать еще одну версию функции strlen,вычисляющей длину строки./* strlen: возвращает длину строки */int strlen(char *s){int n;for (n = 0; *s != '\0' ; s++)n++;return n;}Так как переменная s — указатель, к ней применима операция ++; s++ не оказывает никакого влияния настроку символов функции, которая обратилась к strlen.

Просто увеличивается на 1 некоторая копияуказателя, находящаяся в личном пользовании функции strlen. Это значит, что все вызовы, такие как:strlen("3дравствуй, мир"); /* строковая константа */strlen(array); /* char array[100]; */strlen(ptr); /* char *ptr; */правомерны.Формальные параметрыchar s[];иchar *s;в определении функции эквивалентны. Мы отдаем предпочтение последнему варианту, поскольку он болееявно сообщает, что s есть указатель. Если функции в качестве аргумента передается имя массива, то онаможет рассматривать его так, как ей удобно — либо, как имя массива, либо как указатель, и поступать с нимсоответственно.

Она может даже использовать оба вида записи, если это покажется уместным и понятным.Функции можно передать часть массива, для этого аргумент должен указывать на начало подмассива.Например, если а — массив, то в записяхf(&a[2])илиf(a+2)функции f передается адрес подмассива, начинающегося с элемента а[2]. Внутри функции f описаниепараметров может выглядеть какf(int arr[]) {…}илиf(int *arr) {…}Следовательно, для f тот факт, что параметр указывает на часть массива, а не на весь массив, не имеетзначения.Если есть уверенность, что элементы массива существуют, то возможно индексирование и в "обратную"сторону по отношению к нулевому элементу; выражения р[-1], р[-2] и т.

д. не противоречат синтаксисуязыка и обращаются к элементам, стоящим непосредственно перед р[0]. Разумеется, нельзя "выходить" заграницы массива и тем самым обращаться к несуществующим объектам.5.4. Адресная арифметикаЕсли р есть указатель на некоторый элемент массива, то р++ увеличивает р так, чтобы он указывал наследующий элемент, а р += i увеличивает его, чтобы он указывал на i-й элемент после того, на которыйуказывал ранее. Эти и подобные конструкции — самые простые примеры арифметики над указателями,называемой также адресной арифметикой.Си последователен и единообразен в своем подходе к адресной арифметике.

Это соединение в одном языкеуказателей, массивов и адресной арифметики — одна из сильных его сторон. Проиллюстрируем сказанноепостроением простого распределителя памяти, состоящего из двух программ. Первая, alloc(n),возвращает указатель р на n последовательно расположенных ячеек типа char; программой, обращающейсяк alloc, эти ячейки могут быть использованы для запоминания символов.

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

В стандартной библиотеке имеются функции malloc иfree, которые делают то же самое, только без упомянутых ограничений; в параграфе 8.7 мы покажем, какони выглядят.Функцию alloc легче всего реализовать, если условиться, что она будет выдавать куски некоторогобольшого массива типа char, который мы назовем allocbuf. Этот массив отдадим в личное пользованиефункциям alloc и afree. Так как они имеют дело с указателями, а не с индексами массива, то другимпрограммам знать его имя не нужно. Кроме того, этот массив можно определить в том же исходном файле,что и alloc и afree, объявив его static, благодаря чему он станет невидимым вне этого файла.

Напрактике такой массив может и вовсе не иметь имени, поскольку его можно запросить с помощью malloc уоперационной системы и получить указатель на некоторый безымянный блок памяти.Естественно, нам нужно знать, сколько элементов массива allocbuf уже занято. Мы введем указательallocp, который будет указывать на первый свободный элемент. Если запрашивается память для nсимволов, то alloc возвращает текущее значение allocp (т. е.

адрес начала свободного блока) и затемувеличивает его на n, чтобы указатель allocp указывал на следующую свободную область. Если жепространства нет, то alloc выдает нуль. Функция afree[р] просто устанавливает allocp в значение р,если оно не выходит за пределы массива allocbuf.Перед вызовом alloc:После вызова alloc:#define ALLOCSIZE 10000 /* размер доступного пространства */static char allocbuf[ALLOCSIZE]; /* память для alloc */static char *allocp = allocbuf; /* указатель на своб. место */char *alloc(int n) /* возвращает указатель на п символов */{if (allocbuf + ALLOCSIZE - allocp >= n) {allocp += n; /* пространство есть */return allocp - n; /* старое р */} else /* пространства нет */return 0;}void afree(char *p) /* освобождает память, на которую указывает р */{if (р >= allocbuf && р < allocbuf + ALLOCSIZE)allocp = р;}В общем случае указатель, как и любую другую переменную, можно инициализировать, но только такимиосмысленными для него значениями, как нуль или выражение, приводящее к адресу ранее определенныхданных соответствующего типа.

Объявлениеstatic char *allocp = allocbuf;определяет allocp как указатель на char и инициализирует его адресом массива allocbuf, посколькуперед началом работы программы массив allocbuf пуст. Указанное объявление могло бы иметь и такойвид:static char *allocp = &allocbuf[0];поскольку имя массива и есть адрес его нулевого элемента.Проверкаif (allocbuf + ALLOCSIZE - allocp >= n) { /* годится */контролирует, достаточно ли пространства, чтобы удовлетворить запрос на n символов.

Если памятидостаточно, то новое значение для allocp должно указывать не далее чем на следующую позицию запоследним элементом allocbuf. При выполнении этого требования alloc выдает указатель на началовыделенного блока символов (обратите внимание на объявление типа самой функции). Если требование невыполняется, функция alloc должна выдать какой-то сигнал о том, что памяти не хватает.

Си гарантирует,что нуль никогда не будет правильным адресом для данных, поэтому мы будем использовать его в качествепризнака аварийного события, в нашем случае нехватки памяти.Указатели и целые не являются взаимозаменяемыми объектами. Константа нуль — единственное исключениеиз этого правила: ее можно присвоить указателю, и указатель можно сравнить с нулевой константой. Чтобыпоказать, что нуль — это специальное значение для указателя, вместо цифры нуль, как правило, записываютNULL — константу, определенную в файле <stdio.h>.

С этого момента и мы будем ею пользоваться.Проверкиif (allocbuf + ALLOCSIZE - allocp >= n) { /* годится */иif (p >= allocbuf && p < allocbuf + ALLOCSIZE)демонстрируют несколько важных свойств арифметики с указателями. Во-первых, при соблюдениинекоторых правил указатели можно сравнивать.Если р и q указывают на элементы одного массива, то к ним можно применять операторы отношения ==, !=,<, >= и т. д. Например, отношение видаp < qистинно, если р указывает на более ранний элемент массива, чем q. Любой указатель всегда можно сравнитьна равенство и неравенство с нулем. А вот для указателей, не указывающих на элементы одного массива,результат арифметических операций или сравнений не определен.

(Существует одно исключение: варифметике с указателями можно использовать адрес несуществующего "следующего за массивом"элемента, т. е. адрес того "элемента", который станет последним, если в массив добавить еще один элемент.)Во-вторых, как вы уже, наверное, заметили, указатели и целые можно складывать и вычитать. Конструкцияр + nозначает адрес объекта, занимающего n-е место после объекта, на который указывает р.

Характеристики

Тип файла
PDF-файл
Размер
2,25 Mb
Тип материала
Высшее учебное заведение

Список файлов книги

Свежие статьи
Популярно сейчас
Как Вы думаете, сколько людей до Вас делали точно такое же задание? 99% студентов выполняют точно такие же задания, как и их предшественники год назад. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
7046
Авторов
на СтудИзбе
259
Средний доход
с одного платного файла
Обучение Подробнее