Главная » Просмотр файлов » С.Б. Липпман, Ж. Лажойе - Язык программирования С++ Вводный курс

С.Б. Липпман, Ж. Лажойе - Язык программирования С++ Вводный курс (1114944), страница 53

Файл №1114944 С.Б. Липпман, Ж. Лажойе - Язык программирования С++ Вводный курс (С.Б. Липпман, Ж. Лажойе - Язык программирования С++ Вводный курс) 53 страницаС.Б. Липпман, Ж. Лажойе - Язык программирования С++ Вводный курс (1114944) страница 532019-05-08СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

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

С++действительно не пропустит подобные вызовы. Текст сообщения будет выглядетьпримерно так:// gcd( "hello", "world" )error: invalid argument types ( const char *, const char * ) -expecting ( int, int )ошибка: неверные типы аргументов ( const char *, const char * ) -ожидается ( int, int )// gcd( 24312 )error: missing value for second argumentошибка: пропущено значение второго аргументаА если вызвать эту функцию с аргументами типа double? Должен ли этот вызоврасцениваться как ошибочный?gcd( 3.14, 6.29 );319С++ для начинающихКак было сказано в разделе 4.14, значение типа double может быть преобразовано в int.Следовательно, считать такой вызов ошибочным было бы слишком сурово.

Вместо этогоаргументы неявно преобразуются в int (отбрасыванием дробной части) и таким образомтребования, налагаемые на типы параметров, выполняются. Поскольку при подобномпреобразовании возможна потеря точности, хороший компилятор выдастпредупреждение. Вызов превращается вgcd( 3, 6 );что дает в результате 3.С++ является строго типизированным языком. Компилятор проверяет аргументы насоответствие типов в каждом вызове функции. Если тип фактического аргумента несоответствует типу формального параметра, то производится попытка неявногопреобразования. Если же это оказывается невозможным или число аргументов неверно,компилятор выдает сообщение об ошибке. Именно поэтому функция должна бытьобъявлена до того, как программа впервые обратится к ней: без объявления компиляторне обладает информацией для проверки типов.Пропуск аргумента при вызове или передача аргумента неуказанного типа часто служилиисточником ошибок в языке С.

Теперь такие погрешности обнаруживаются на этапекомпиляции.Упражнение 7.1(a) set( int *, int );(b) void func();(c) string error( int );Какие из следующих прототипов функций содержат ошибки? Объясните.(d) arr[10] sum( int *, int );Упражнение 7.2Напишите прототипы для следующих функций:Функция с именем compare, имеющая два параметра типа ссылки на класс matrix ивозвращающая значение типа bool.Функция с именем extract без параметров, возвращающая контейнер set для хранениязначений типа int. (Контейнерный тип set описывался в разделе 6.13.)Упражнение 7.3double calc( double );int count( const string &, char );void sum( vector<int> &, int );Имеются объявления функций:vector<int> vec( 10 );Какие из следующих вызовов содержат ошибки и почему?320С++ для начинающих(a) calc( 23.4, 55.1 );(b) count( "abcda", 'a' );(c) sum( vec, 43.8 );(d) calc( 66 );7.3. Передача аргументовФункции используют память из стека программы. Некоторая область стека отводитсяфункции и остается связанной с ней до окончания ее работы, по завершении которойотведенная ей память освобождается и может быть занята другой функцией.

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

Локальные копии теряются при выходе из функции.Значения аргументов при передаче по значению не меняются. Следовательно,программист не должен заботиться о сохранении и восстановлении их значений привызове функции. Без этого механизма любой вызов мог бы привести к нежелательномуизменению аргументов, не объявленных константными явно. Передача по значениюосвобождает человека от лишних забот в наиболее типичной ситуации.Однако такой способ передачи аргументов может не устраивать нас в следующихслучаях:•передача большого объекта типа класса. Временные и пространственныерасходы на размещение и копирование такого объекта могут оказатьсянеприемлемыми для реальной программы;•иногда значения аргументов должны быть модифицированы внутри функции.Например, swap() должна обменять значения своих аргументов, что невозможно// swap() не меняет значений своих аргументов!void swap( int vl, int v2 ) {int tmp = v2;v2 = vl;vl = tmp;при передаче по значению:}swap() обменивает значения локальных копий своих аргументов.

Те же переменные, чтобыли использованы в качестве аргументов при вызове, остаются неизменными. Этоможно проиллюстрировать, написав небольшую программу:321С++ для начинающих322#include <iostream>void swap( int, int );int main() {int i = 10;int j = 20;cout << "Перед swap():\ti: "<< i << "\tj: " << j << endl;swap( i, j );cout << "После swap():\ti: "<< i << "\tj: " << j << endl;return 0;}Результат выполнения программы:Перед swap():После swap():i: 10i: 10j: 20j: 20Достичь желаемого можно двумя способами. Первый – объявление параметров// pswap() обменивает значения объектов,// адресуемых указателями vl и v2void pswap( int *vl, int *v2 ) {int tmp = *v2;*v2 = *vl;*vl = tmp;указателями. Вот как будет выглядеть реализация swap() в этом случае:}Функция main() тоже нуждается в модификации.

Вместо передачи самих объектовнеобходимо передавать их адреса:pswap( &i, &j );Теперь программа работает правильно:Перед swap():После swap():i: 10i: 20j: 20j: 10Альтернативой может стать объявление параметров ссылками. В данном случаереализация swap() выглядит так:С++ для начинающих// rswap() обменивает значения объектов,// на которые ссылаются vl и v2void rswap( int &vl, int &v2 ) {int tmp = v2;v2 = vl;vl = tmp;}Вызов этой функции из main() аналогичен вызову первоначальной функции swap():rswap( i, j );Выполнив программу main(), мы снова получим верный результат.7.3.1.

Параметры-ссылкиИспользование ссылок в качестве параметров модифицирует стандартный механизмпередачи по значению. При такой передаче функция манипулирует локальными копиямиаргументов. Используя параметры-ссылки, она получает l-значения своих аргументов иможет изменять их.В каких случаях применение параметров-ссылок оправданно? Во-первых, тогда, когдабез использования ссылок пришлось бы менять типы параметров на указатели (см.приведенную выше функцию swap()). Во-вторых, при необходимости вернуть изфункции несколько значений. В-третьих, для передачи большого объекта типа класса.Рассмотрим два последних случая подробнее.Как пример функции, использующей параметр-ссылку для возврата дополнительногозначения, возьмем look_up(), которая будет искать заданную величину в векторе целыхчисел. В случае успеха look_up() вернет итератор, указывающий на найденный элемент,иначе – на элемент, расположенный за конечным. Если величина содержится в векторенесколько раз, итератор будет указывать на первое вхождение.

Кроме того,дополнительный параметр-ссылка occurs возвращает количество найденных элементов.323С++ для начинающих324#include <vector>// параметр-ссылка 'occurs'// содержит второе возвращаемое значениеvector<int>::const_iterator look_up(const vector<int> &vec,int value,int &occurs )// искомое значение// количество вхождений{// res_iter инициализируется значением// следующего за конечным элементаvector<int>::const_iterator res_iter = vec.end();occurs = 0;for ( vector<int>::const_iterator iter = vec.begin();iter != vec.end();++iter )if ( *iter == value ){if ( res_iter == vec.end() )res_iter = iter;++occurs;}return res_iter;}Третий случай, когда использование параметра-ссылки может быть полезно, – этобольшой объект типа класса в качестве аргумента. При передаче по значению объектбудет копироваться целиком при каждом вызове функции, что для больших объектовможет привести к потере эффективности.

Используя параметр-ссылку, функция получаетдоступ к той области памяти, где размещен сам объект, без создания дополнительнойclass Huge { public: double stuff[1000]; };extern int calc( const Huge & );int main() {Huge table[ 1000 ];// ... инициализация tableint sum = 0;for ( int ix=0; ix < 1000; ++ix )// calc() ссылается на элемент массива// типа Hugesum += calc( tab1e[ix] );// ...копии. Например:}Может возникнуть желание использовать параметр-ссылку, чтобы избежать созданиякопии большого объекта, но в то же время не дать вызываемой функции возможностиизменять значение аргумента. Если параметр-ссылка не должен модифицироватьсявнутри функции, то стоит объявить его как ссылку на константу. В такой ситуацииС++ для начинающихкомпилятор способен распознать и пресечь попытку непреднамеренного изменениязначения аргумента.В следующем примере нарушается константность параметра xx функции foo().Поскольку параметр функции foo_bar() не является ссылкой на константу, то нетгарантии, что вызов foo_bar() не изменит значения аргумента.

Компиляторclass X;extern int foo_bar( X& );int foo( const X& xx ) {// ошибка: константа передается// функции с параметром неконстантного типаreturn foo_bar( xx );сигнализирует об ошибке:}Для того чтобы программа компилировалась, мы должны изменить тип параметраextern int foo_bar( const X& );foo_bar(). Подойдет любой из следующих двух вариантов:extern int foo_bar( X ); // передача по значениюint foo( const X &xx ) {// ...X x2 = xx; // создать копию значения// foo_bar() может поменять x2,// xx останется нетронутымreturn foo_bar( x2 ); // правильноВместо этого можно передать копию xx, которую позволено менять:}Параметр-ссылка может именовать любой встроенный тип данных.

В частности,разрешается объявить параметр как ссылку на указатель, если программист хочетизменить значение самого указателя, а не объекта, который он адресует. Вот примерvoid ptrswap( int *&vl, int *&v2 ) {int *trnp = v2;v2 = vl;vl = tmp;функции, обменивающей друг с другом значения двух указателей:}Объявлениеint *&v1;325С++ для начинающих326должно читаться справа налево: v1 является ссылкой на указатель на объект типа int.Модифицируем функцию main(), которая вызывала rswap(), для проверки работы#include <iostream>void ptrswap( int *&vl, int *&v2 );int main() {int i = 10;int j = 20;int *pi = &i;int *pj = &j;cout << "Перед ptrswap():\tpi: "<< *pi << "\tpj: " << *pj << endl;ptrswap( pi, pj );cout << "После ptrswap():\tpi: "<< *pi << "\tpj: " << pj << endl;return 0;ptrswap():}Вот результат работы программы:Перед ptrswap():После ptrswap():pi: 10pi: 20pj: 20pj: 107.3.2.

Параметры-ссылки и параметры-указателиКогда же лучше использовать параметры-ссылки, а когда – параметры-указатели? Вконце концов, и те и другие позволяют функции модифицировать объекты, эффективнопередавать в функцию большие объекты типа класса. Что выбрать: объявить параметрссылкой или указателем?Как было сказано в разделе 3.6, ссылка может быть один раз инициализированазначением объекта, и впоследствии изменить ее нельзя.

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

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

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

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