Главная » Просмотр файлов » B. Stroustrup - The C++ Programming Language

B. Stroustrup - The C++ Programming Language (794319), страница 75

Файл №794319 B. Stroustrup - The C++ Programming Language (B. Stroustrup - The C++ Programming Language) 75 страницаB. Stroustrup - The C++ Programming Language (794319) страница 752019-05-09СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

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

In pointerassignments, the complete function type must match exactly. For example:void (∗pf)(string);void f1(string);int f2(string);void f3(int∗);// pointer to void(string)// void(string)// int(string)// void(int*)Section 12.5void f(){pf = &f1;pf = &f2;pf = &f3;Pointer to Function333// OK// error : bad return type// error: bad argument typepf("Hera");pf(1);// OK// error: bad argument typeint i = pf("Zeus");// error: void assigned to int}The rules for argument passing are the same for calls directly to a function and for calls to a function through a pointer.You can convert a pointer to function to a different pointer-to-function type, but you must castthe resulting pointer back to its original type or strange things may happen:using P1 = int(∗)(int∗);using P2 = void(∗)(void);void f(P1 pf){P2 pf2 = reinterpret_cast<P2>(pf)pf2();P1 pf1 = reinterpret_cast<P1>(pf2);int x = 7;int y = pf1(&x);// ...}// likely serious problem// convert pf2 ‘‘back again’’// OKWe need the nastiest of casts, reinterpret_cast, to do conversion of pointer-to-function types.

Thereason is that the result of using a pointer to function of the wrong type is so unpredictable and system-dependent. For example, in the example above, the called function may write to the objectpointed to by its argument, but the call pf2() didn’t supply any argument!Pointers to functions provide a way of parameterizing algorithms. Because C does not havefunction objects (§3.4.3) or lambda expressions (§11.4), pointers to functions are widely used asfunction arguments in C-style code. For example, we can provide the comparison operation neededby a sorting function as a pointer to function:using CFT = int(const void∗, const void∗);void ssort(void∗ base, size_t n, size_t sz, CFT cmp)/*Sor t the "n" elements of vector "base" into increasing orderusing the comparison function pointed to by "cmp".The elements are of size "sz".Shell sort (Knuth, Vol3, pg84)*/334FunctionsChapter 12{for (int gap=n/2; 0<gap; gap/=2)for (int i=gap; i!=n; i++)for (int j=i−gap; 0<=j; j−=gap) {char∗ b = static_cast<char∗>(base);// necessar y castchar∗ pj = b+j∗sz;// &base[j]char∗ pjg = b+(j+gap)∗sz;// &base[j+gap]if (cmp(pjg,pj)<0) {// swap base[j] and base[j+gap]:for (int k=0; k!=sz; k++) {char temp = pj[k];pj[k] = pjg[k];pjg[k] = temp;}}}}The ssort() routine does not know the type of the objects it sorts, only the number of elements (thearray size), the size of each element, and the function to call to perform a comparison.

The type ofssort() was chosen to be the same as the type of the standard C library sort routine, qsort(). Realprograms use qsort(), the C++ standard-library algorithm sort (§32.6), or a specialized sort routine.This style of code is common in C, but it is not the most elegant way of expressing this algorithm inC++ (see §23.5, §25.3.4.1).Such a sort function could be used to sort a table such as this:struct User {const char∗ name;const char∗ id;int dept;};vector<User> heads = {"Ritchie D.M.","Sethi R.","Szymanski T.G.","Schryer N.L.","Schryer N.L.","Kernighan B.W.",};"dmr","ravi","tgs","nls","nls","bwk",11271,11272,11273,11274,11275,11276void print_id(vector<User>& v){for (auto& x : v)cout << x.name << '\t' << x.id << '\t' << x.dept << '\n';}To be able to sort, we must first define appropriate comparison functions. A comparison functionmust return a negative value if its first argument is less than the second, zero if the arguments areequal, and a positive number otherwise:Section 12.5Pointer to Function335int cmp1(const void∗ p, const void∗ q) // Compare name strings{return strcmp(static_cast<const User∗>(p)−>name,static_cast<const User∗>(q)−>name);}int cmp2(const void∗ p, const void∗ q) // Compare dept numbers{return static_cast<const User∗>(p)−>dept − static_cast<const User∗>(q)−>dept;}There is no implicit conversion of argument or return types when pointers to functions are assignedor initialized.

This means that you cannot avoid the ugly and error-prone casts by writing:int cmp3(const User∗ p, const User∗ q) // Compare ids{return strcmp(p−>id,q−>id);}The reason is that accepting cmp3 as an argument to ssort() would violate the guarantee thatwill be called with arguments of type const User∗ (see also §15.2.6).This program sorts and prints:int main(){cout << "Heads in alphabetical order:\n";ssort(heads,6,sizeof(User),cmp1);print_id(heads);cout << '\n';cout << "Heads in order of department number:\n";ssort(heads,6,sizeof(User),cmp2);print_id(heads);}To compare, we can equivalently write:int main(){cout << "Heads in alphabetical order:\n";sort(heads.begin(), head.end(),[](const User& x, const User& y) { return x.name<y.name; });print_id(heads);cout << '\n';cout << "Heads in order of department number:\n";sort(heads.begin(), head.end(),[](const User& x, const User& y) { return x.dept<y.dept; });print_id(heads);}cmp3336FunctionsChapter 12No mention of sizes is needed nor any helper functions.

If the explicit use of begin() andannoying, it can be eliminated by using a version of sort() that takes a container (§14.4.5):end()issort(heads,[](const User& x, const User& y) { return x.name<y.name; });You can take the address of an overloaded function by assigning to or initializing a pointer to function.

In that case, the type of the target is used to select from the set of overloaded functions. Forexample:void f(int);int f(char);void (∗pf1)(int) = &f;int (∗pf2)(char) = &f;void (∗pf3)(char) = &f;// void f(int)// int f(char)// error: no void f(char)It is also possible to take the address of member functions (§20.6), but a pointer to member function is quite different from a pointer to (nonmember) function.A pointer to a noexcept function can be declared noexcept. For example:void f(int) noexcept;void g(int);void (∗p1)(int) = f;void (∗p2)(int) noexcept = f;void (∗p3)(int) noexcept = g;// OK: but we throw away useful information// OK: we preser ve the noexcept information// error : we don’t know that g doesn’t throwA pointer to function must reflect the linkage of a function (§15.2.6).

Neither linkage specificationnor noexcept may appear in type aliases:using Pc = extern "C" void(int);using Pn = void(int) noexcept;// error : linkage specification in alias// error : noexcept in alias12.6 MacrosMacros are very important in C but have far fewer uses in C++. The first rule about macros is:don’t use them unless you have to. Almost every macro demonstrates a flaw in the programminglanguage, in the program, or in the programmer. Because they rearrange the program text beforethe compiler proper sees it, macros are also a major problem for many programming support tools.So when you use macros, you should expect inferior service from tools such as debuggers, crossreference tools, and profilers. If you must use macros, please read the reference manual for yourown implementation of the C++ preprocessor carefully and try not to be too clever.

Also, to warnreaders, follow the convention to name macros using lots of capital letters. The syntax of macros ispresented in §iso.16.3.I recommend using macros only for conditional compilation (§12.6.1) and in particular forinclude guards (§15.3.3).A simple macro is defined like this:#define NAME rest of lineSection 12.6Macros337Where NAME is encountered as a token, it is replaced by rest of line. For example:named = NAMEwill expand intonamed = rest of lineA macro can also be defined to take arguments.

For example:#define MAC(x,y) argument1: x argument2: yWhen MAC is used, two argument strings must be presented. They will replace x and y when MAC()is expanded. For example:expanded = MAC(foo bar, yuk yuk)will be expanded intoexpanded = argument1: foo bar argument2: yuk yukMacro names cannot be overloaded, and the macro preprocessor cannot handle recursive calls:#define PRINT(a,b) cout<<(a)<<(b)#define PRINT(a,b,c) cout<<(a)<<(b)<<(c)/* trouble?: redefines, does not overload */#define FAC(n) (n>1)?n∗FAC(n−1):1/* trouble: recursive macro */Macros manipulate character strings and know little about C++ syntax and nothing about C++types or scope rules.

Only the expanded form of a macro is seen by the compiler, so an error in amacro will be reported when the macro is expanded, not when it is defined. This leads to veryobscure error messages.Here are some plausible macros:#define CASE break;case#define FOREVER for(;;)Here are some completely unnecessary macros:#define PI 3.141593#define BEGIN {#define END }Here are some dangerous macros:#define SQUARE(a) a∗a#define INCR_xx (xx)++To see why they are dangerous, try expanding this:int xx = 0;// global countervoid f(int xx){int y = SQUARE(xx+2);INCR_xx;}// y=xx+2*xx+2; that is, y=xx+(2*xx)+2// increments argument xx (not the global xx)338FunctionsChapter 12If you must use a macro, use the scope resolution operator, ::, when referring to global names(§6.3.4) and enclose occurrences of a macro argument name in parentheses whenever possible.

Forexample:#define MIN(a,b) (((a)<(b))?(a):(b))This handles the simpler syntax problems (which are often caught by compilers), but not the problems with side effects. For example:int x = 1;int y = 10;int z = MIN(x++,y++);// x becomes 3; y becomes 11If you must write macros complicated enough to require comments, it is wise to use /∗ ∗/ commentsbecause old C preprocessors that do not know about // comments are sometimes used as part of C++tools. For example:#define M2(a) something(a)/* thoughtful comment */Using macros, you can design your own private language.

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

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

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

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