|
Программирование >> Унарные и бинарные операторы
ся до суммирования. То есть при входе в цикл переменная 1 будет равна 1, затем i увеличится на 1, став равной 2, и уже двойка прибавится к переменной sum. Значит, следуЮН1ИЙ цикл сложит все числа от 2 до 1001, то есть сделает не совсем то, что от пего ожидали: while(i<=N) sum+=++i: Задача 3.5. Докажите, что цикл while(i<=N) sum+=++i при начальном значении суммы sum-0 складывает все числа от i+1 до N+1. Операторы автоувеличения (++) и автоуменьшения (--) позволяют очень компактно записать инструкцию, но пользоваться ими надо с осторожностью, ведь переменная, к которой применен оператор ++ (или --), если она еще раз встретится в инструкции, сделает ее результат непредсказуемым. Пусть, например, sum=0, а i-7. Чему тогда будут равны переменные sum и i после выполнения следующей инструкции: sum=i++*i++: Что сделает компилятор: умножит 7x7, зашлет в sum результат (49) и потом дважды увеличит i? Или же возьмет первый операнд 7, увеличит его, у.множит 7x8, зашлет результат (56) в sum, затем еще раз увеличит i? Оказывается, может произойти все что угодно, и не имеет смысла даже думать об этом. Просто нужно понять, что такие опасные двусмысленные выражения использовать нельзя никогда, ни при кокш: обстоятельствах. До сих пор нам был известен только один цикл whi 1е(), именно с его помощью были впервые просуммированы числа от О до 1000. Но в С++ есть еще одна инструкция fdrO, особо удобная, когда число оборотов цикла в точности известно. С ее помощью программа суммирования 1000 чисел от 1 до 1000 будет такой, как в листинге 3.9. /1ИСТИНГ 3.9 finclude <iostream> using namespace std; int main(){ int N=1000: int sum=0; forCint i=l:i<=N:i++) sum+=i: cout sum= sum endl; } Инструкция for() управляется тремя выражениями, стоящими в круглых скобках и разделенными точкой с запятой. Первое выражение задает начальное значение переменной, которая меняется в цикле. Причем, такую переменную можно прямо объявить, как это у нас и сделано (int 1=1;). Второе выражение (i<-N) задает условие выполнения цикла, наконец, третье выражение (i++) задает шаг изменения переменной после каждого оборота цикла. Чтобы знать досконально, как работает цикл forO, попробуем всухую прокрутить его несколько раз. Итак, перед первым оборотом переменная sum равна нулю, а 1 - единице. Прежде чем выполнять инструкцию sum+=i, цикл проверяет условие 1<=М, а поскольку в этот момент 1=1, а N 1000. условие выполняется, и к переменной sum прибавляется текущее значение i, то есть единица. Теперь sum=l и выполняется инструкция изменения переменной 1. В нашем случае это i++, а поскольку текущее значение переменной 1 все еще единица, оно становится равной двум, и теперь все готово к новому обороту цикла, по сначала проверяется условие i<=N. В этот момент 1=2, условие выполняется, к переменной sum, равной в этот момент единице, прибавляется текущее значение 1-2, и переменная sum становится равной трем. Дальнейшие обороты цикла ничем не отличаются от только что описанных, стоит разве что посмотреть на последний оборот. Очевидно, в этот момент 52 Глава 3. Операторы i=1000, условие i<=N выполняется, и к переменной sum прибавляется 1000, затем переменная i увеличивается на единицу, становится равной 1001, условие i<=N не выполняется, цикл прекращает работу, и программа, не прибавляя 1001 к sum, переходит к следующей за циклом инструкции, то есть к выводу результатов на экран. Этот раздел оказался длинным, но и сейчас его не удастся закончить, потому что придется сказать несколько слов о названии языка - С++. Применение оператора автоувеличения к некоему объекту С означает, что С++ - улучшенная версия языка С, разработанного Деннисом Ритчи и Кеном Томпсоном в начале 70-х годов прошлого века. Язык С (мы обычно говорим Си) стал необычайно популярен и, назвав новый язык С++, Бьярн Строуструп, его создатель, сделал гениальный маркетинговый ход, во многом определивший немыслимый успех С++. Поначалу язык С++ действительно был улучшенным С, но неумолимая логика развития привела к полному отходу С++ от С, и сейчас это как бы два существующих вместе совершенно разных языка, между которыми сохраняется связь, то есть наработанное для С еще используется в С++. Языки С++ и С по-прежнему совместимы снизу вверх , то есть компилятор С++ понимает почти любую программу, написанную на С. Но сам язык С++ уже настолько далек от С, что его следует изучать отдельно и без оглядки на предка . ГЛАВА 4 Строки и контейнеры Приговор в разделе Умные операторы главы 3 мы уже встречались со специальными объск-гами - строками, задаваемыми ключевым словом string. Было показано, как меняется смысл операторов =, +, < и т. д., когда они используются с такими объектами, как строки. Оператор + хорош и логичен при соединении строк, оператор = - при задании начального значения строки. Но было бы неправильно вьпюлнять все действия с объектами с помоп1ью операторов. Строки гораздо сложнее чисел, и никаких операторов не хватит, чтобы выполнить все возможные действия. Да и выглядеть это будет непривычно. Какой, например, оператор выбрать для вставки одной строки внутрь другой? Вот поэтому основная часть операций с объектами проводится с по-моп1ью их собственных функций. Рассмотрим в качестве примера классическую задачу: вставить запятую в приговор: Казнить нельзя помиловать . В программе, показанной в листинге 4.1, для этого исполь-зуется функция insertO. Листинг 4.1 #include <iostreatn> #include <string> using namespace std: int main(){ string sentence-- Казнить нельзя помиловать : sentence.insert(14. . ): cout sentence endl: У функции insertO, показанной в листинге, два аргумента: первый - это позиция, куда вставляется стро- ка (в на1пем случае - 14), и сама вставляемая строка (в на1пем случае - просто запятая). Представьте себе, что от правильного положения запятой зависит ваша жизнь. Значит, нужно предельно точно определить номер символа, с которого начнется вставка. А для этого необходимо знать, что символы в строке С++ нумеруются начиная с нуля! Буква К имеет нулевой помер, буква а - первый, а буква я - тринадцатый. Значит, запятая должна быть четырнадцатой, и профамма, показанная в листинге 4.1, выведет на экран фразу Казнить нeJU.зя, помиловать . Познакомившись с функцией insertO, имеет смысл еще раз вернуться к операторам. Дело в том, что почти все операторы дублируются соответствуюп1ей собственной функцией объекта string. Вспомним фрагмент профаммы из главы 3, в котором соединяются две строки - Здравствуй и Мама! : string a.b.c; а= 3дравствуй ; Ь= Мана! : с=а + Ь: Поскольку работу оператора + выполняет функция appendO, этот фрагмент можно переписать так: string a.b.c: а = Здравствуй : b = Мама! : с = a.append(b); То же самое можно записать короче: string a.b; а = Здравствуй : b = a.append( MaMa! ); В двух последних примерах мы, сами того не ведая, познакомились с важненншм свойством собственной функции - способностью не только управлять объектом, но и возвращать полученные результаты во внешний мир. Запись b-a.append( MaMa! ) возможна только
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |