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

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

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

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

Предположим, что n содержит 5, тогдаx = n++;установит x в значение 5, аx = ++n;установит х в значение 6. И в том и другом случае n станет равным 6. Операторы инкремента и декрементаможно применять только к переменным. Выражения вроде (i+j)++ недопустимы.Если требуется только увеличить или уменьшить значение переменной (но не получить ее значение), какнапримерif (c == '\n')nl++;то безразлично, какой оператор выбрать — префиксный или постфиксный. Но существуют ситуации, когдатребуется оператор вполне определенного типа.

Например, рассмотрим функцию squeeze(s, с), котораяудаляет из строки s все символы, совпадающие с c:/* squeeze: удаляет все с из s */void squeeze(char s[], int с){int i, j;for (i = j = 0; s[i] != '\0'; i++)if (s[i] != c)s[j++] = s[i];s[i] = '\0';}Каждый раз, когда встречается символ, отличный от с, он копируется в текущую j-ю позицию, и только послеэтого переменная j увеличивается на 1, подготавливаясь таким образом к приему следующего символа.

Это вточности совпадает со следующими действиями:if (s[i] != с) {s[j] = s[i];j++;}Другой пример — функция getline, которая нам известна по главе 1. Приведенную там записьif (с == '\n' ) {s[i] = с;++i;}можно переписать более компактно:if (с == '\n' )s[i++] = с;В качестве третьего примера рассмотрим стандартную функцию strcat(s, t), которая строку t помещаетв конец строки s. Предполагается, что в s достаточно места, чтобы разместить там суммарную строку. Мынаписали strcat так, что она не возвращает никакого результата.

На самом деле библиотечная strcatвозвращает указатель на результирующую строку./* strcat: помещает t в конец s; s достаточно велика */void strcat (char s[], char t[]){int i, j;i = j = 0;while (s[i] != '\0') /* находим конец s */i++;while ((s[i++] = t[j++]) != '\0') /* копируем t */;}При копировании очередного символа из t в s постфиксный оператор ++ применяется и к i, и к j, чтобы накаждом шаге цикла переменные i и j правильно отслеживали позиции перемещаемого символа.Упражнение 2.4.

Напишите версию функции squeeze(s1, s2), которая удаляет из s1 все символы,встречающиеся в строке s2.Упражнение 2.5. Напишите функцию any(s1, s2), которая возвращает либо ту позицию в s1, где стоитпервый символ, совпавший с любым из символов в s2, либо -1 (если ни один символ из s1 не совпадает ссимволами из s2). (Стандартная библиотечная функция strpbrk делает то же самое, но выдает не номерпозиции символа, а указатель на символ.)2.9.

Побитовые операторыВ Си имеются шесть операторов для манипулирования с битами. Их можно применять только кцелочисленным операндам, т. е. к операндам типов char, short, int и long, знаковым и беззнаковым.&— побитовое И.|— побитовое ИЛИ.^— побитовое исключающее ИЛИ.<<— сдвиг влево.>>— сдвиг вправо.~— побитовое отрицание (унарный).1^1, 0^0 => 01^0, 0^1 => 1Оператор & (побитовое И) часто используется для обнуления некоторой группы разрядов. Напримерn = n & 0177;обнуляет в n все разряды, кроме младших семи.Оператор | (побитовое ИЛИ) применяют для установки разрядов; так,х = х | SET_ON;устанавливает единицы в тех разрядах х, которым соответствуют единицы в SET_ON.Оператор ^ (побитовое исключающее ИЛИ) в каждом разряде установит 1, если соответствующие разрядыоперандов имеют различные значения, и 0, когда они совпадают.Поразрядные операторы & и | следует отличать от логических операторов && и ||, которые при вычислениислева направо дают значение истинности.

Например, если x равно 1, а y равно 2, то x & y даст нуль, а x &&у единицу.Операторы << и >> сдвигают влево или вправо свой левый операнд на число битовых позиций, задаваемоеправым операндом, который должен быть неотрицательным. Так, х << 2 сдвигает значение х влево на 2позиции, заполняя освобождающиеся биты нулями, что эквивалентно умножению х на 4. Сдвиг вправобеззнаковой величины всегда сопровождается заполнением освобождающихся разрядов нулями. Сдвигвправо знаковой величины на одних машинах происходит с распространением знака ("арифметическийсдвиг"), на других — с заполнением освобождающихся разрядов нулями ("логический сдвиг").Унарный оператор ~ поразрядно "обращает" целое т.

е. превращает каждый единичный бит в нулевой инаоборот. Напримерх = х & ~077обнуляет в х последние 6 разрядов. Заметим, что запись х & ~077 не зависит от длины слова, и,следовательно, она лучше, чем х & 0177700, поскольку последняя подразумевает, что х занимает 16битов. Не зависимая от машины форма записи ~077 не потребует дополнительных затрат при счете, так как~077 — константное выражение, которое будет вычислено во время компиляции.Для иллюстрации некоторых побитовых операций рассмотрим функцию getbits(x, p, n), котораяформирует поле в n битов, вырезанных из х, начиная с позиции p, прижимая его к правому краю.Предполагается, что 0-й бит — крайний правый бит, а n и p — осмысленные положительные числа.Например, getbits(x, 4, 3) вернет в качестве результата 4, 3 и 2-й биты значения х, прижимая их кправому краю.

Вот эта функция:/* getbits: получает п бит, начиная с р-й позиции */unsigned getbits(unsigned х, int p, int n){return (x >> (p+1-n)) & ~(~0 << n);}Выражение х >> (p+1-n) сдвигает нужное нам поле к правому краю. Константа ~0 состоит из однихединиц, и ее сдвиг влево на n бит (~0 << n)приведет к тому, что правый край этой константы займут nнулевых разрядов. Еще одна операция побитовой инверсии ~ позволяет получить справа n единиц.Упражнение 2.6.

Напишите функцию setbits(x, p, n, y), возвращающую значение x, в котором nбитов, начиная с p-й позиции, заменены на n правых разрядов из y (остальные биты не изменяются).Упражнение 2.7. Напишите функцию invert(х, р, n), возвращающую значение x с инвертированнымиn битами, начиная с позиции p (остальные биты не изменяются).Упражнение 2.8. Напишите функцию rightrot(х, n), которая циклически сдвигает x вправо на nразрядов.2.10. Операторы и выражения присваиванияВыражениеi = i + 2в котором стоящая слева переменная повторяется и справа, можно написать в сжатом виде:i += 2Оператор +=, как и =, называется оператором присваивания.Большинству бинарных операторов (аналогичных + и имеющих левый и правый операнды) соответствуютоператоры присваивания ор=, где ор — один из операторов+*/%<<>>&^|Если выр1 и выр2 — выражения, товыр1 ор= выр2эквивалентновыр1 = (выр1) ор (выр2)с той лишь разницей, что выр1 вычисляется только один раз.

Обратите внимание на скобки вокруг выр2:x *= y + 1эквивалентноx = x * (y + 1)но неx = x * y + 1В качестве примера приведем функцию bitcount, подсчитывающую число единичных битов в своемаргументе целочисленного типа./* bitcount: подсчет единиц в х */int bitcount (unsigned x){int b;for (b = 0; x != 0; x >>= 1)if (x & 01)b++;return b;}Независимо от машины, на которой будет работать эта программа, объявление аргумента x как unsignedгарантирует, что при правом сдвиге освобождающиеся биты будут заполняться нулями, а не знаковым битом.Помимо краткости операторы присваивания обладают тем преимуществом, что они более соответствуюттому, как человек мыслит.

Мы говорим "прибавить 2 к i" или "увеличить i на 2", а не "взять i, добавить 2 изатем вернуть результат в i", так что выражение i += 2 лучше, чем i = i + 2. Кроме того, в сложныхвыражениях вродеyyval[yypv[p3+p4] + yypv[p1+p2]] += 2благодаря оператору присваивания += запись становится более легкой для понимания, так как читателю притакой записи не потребуется старательно сравнивать два длинных выражения, совпадают ли они, иливыяснять, почему они не совпадают. Следует иметь в виду и то, что подобные операторы присваивания могутпомочь компилятору сгенерировать более эффективный код.Мы уже видели, что присваивание вырабатывает значение и может применяться внутри выражения; вотсамый расхожий пример:while ((с = getchar()) != EOF)…В выражениях встречаются и другие операторы присваивания (+=, -= и т.д.), хотя и реже.Типом и значением любого выражения присваивания являются тип и значение его левого операнда послезавершения присваивания.Упражнение 2.9.

Применительно к числам, в представлении которых использован дополнительный код,выражение х &= (х-1) уничтожает самую правую 1 в х. Объясните, почему. Используйте это наблюдениепри написании более быстрого варианта функции bitcount.2.11. Условные выраженияИнструкцииif (а > b)z = a;elsez = b;пересылают в z большее из двух значений a и b. Условное выражение, написанное с помощью тернарного(т.е. имеющего три операнда) оператора ?:, представляет собой другой способ записи этой и подобных ейконструкций. В выражениивыр1 ? выр2 : выр3первым вычисляется выражение выр1. Если его значение не нуль (истина), то вычисляется выражение выр2 изначение этого выражения становится значением всего условного выражения. В противном случаевычисляется выражение выр3 и его значение становится значением условного выражения.

Следует отметить,что из выражений выр2 и выр3 вычисляется только одно из них. Таким образом, чтобы установить в z большееиз a и b, можно написатьz = (a > b) ? а : b; /* z = max(a, b) */Следует заметить, что условное выражение и в самом деле является выражением, и его можно использоватьв любом месте, где допускается выражение. Если выр2 и выр3 принадлежат разным типам, то тип результатаопределяется правилами преобразования, о которых шла речь в этой главе ранее. Например, если f имееттип float, a n — тип int, то типом выражения(n > 0) ? f : nбудет float вне зависимости от того, положительно значение n или нет.Заключать в скобки первое выражение в условном выражении не обязательно, так как приоритет ?: оченьнизкий (более низкий приоритет имеет только присваивание), однако мы рекомендуем всегда это делать,поскольку благодаря обрамляющим скобкам условие в выражении лучше воспринимается.Условное выражение часто позволяет сократить программу.

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

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

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

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