А.В.Столяров. Введение в язык Си++

image of the cover

Аннотация

Краткое (объём третьего издания — 127 страниц) введение в язык Си++. Содержание построено по принципу плавного перехода от средств чистого Си: в начале даётся определение ООП как парадигмы, основанной на обмене сообщениями, затем вводится метод для обычной открытой структуры, уже после этого рассказывается о защите и её предназначении, затем (поскольку теперь это необходимо) вводятся конструкторы и деструкторы, и т.д. Так называемая "стандартная библиотека" Си++ (известная также под названием STL) в книге не упоминается вообще, поскольку если начать изучение Си++ с STL, есть риск никогда не узнать сам язык. Для ввода-вывода в примерах используются функции библиотеки Си (printf и др.)

В третьем издании добавлены параграфы, посвящённые временными и анонимным объектам, а также сокрытию имён при наследовании; исправлены замеченные ошибки и в ряде мест даны дополнительные пояснения.

Публикация в бумажном варианте

Третье издание опубликовано издательством МАКС Пресс (Москва) в 2012 году. Книга издана при поддержке компании Юниконтроллерз.

second edition coverВторое издание опубликовано издательством МАКС Пресс (Москва) в 2011 году. ISBN 978-5-317-03552-5.



first edition cover Первое издание публиковалось РИО МГТУ ГА в 2008 г. под заголовком «Методы и средства визуального проектирования. Раздел "введение в язык C++"». ISBN 978-5-86311-660-0


Электронная версия

Электронная версия третьего издания, идентичная печатной версии, доступна здесь: http://www.stolyarov.info/books/pdf/cppintro3.pdf


Электронная версия второго издания доступна здесь: http://www.stolyarov.info/books/pdf/cppintro2.pdf

Электронная версия первого издания доступна здесь: http://www.stolyarov.info/books/pdf/cppintro.pdf Внимание! В старых версиях имеются известные автору фактические ошибки!

Статус бумажной версии

Поступала в свободную продажу; к настоящему моменту почти полностью распродана; последний экземпляр, предназначенный к продаже, ожидает своего покупателя.

Прикрепленный файлРазмер
Исходный текст примера "Разреженный массив"3.61 кб
Модификация примера "Разреженный массив" с использованием шаблонов3.76 кб
Исходный текст примера MultiMatrix из последней главы1.93 кб

http://habrahabr.ru/post/1517

http://habrahabr.ru/post/151760/
Доступен предзаказ 4-го издания «The C++ Programming Language» by Bjarne Stroustrup

Интересно будит ли так же отличатся спецы обученные до 4-го издание и после него? (как вы заметили своей книги для 3-го).

Не думаю что в нём автор решил разделять С++ и STL, скорее даже наоборот, ввиду появившихся новых контейнеров.

Логичный следующий шаг, да

Не думаю, что будут кардинальные отличия. Всё, что Страуструп сделал до третьего издания, внушает уважение, всё, что позже — вызывает недоумение.

Пора новый язык изобретать.

Спасибо за

Спасибо за книгу, очень хорошо "прочистила" мозг - до этого многими частями языка пользовался как обезьяна - не особо понимая их смысл и цель существования. Этим Ваша книга и ценна, что много разъясняет.

Пожалуйста-пожалуйста,

заходите ещё :)

Если не секрет, а о каких именно возможностях языка идёт речь? Вопрос не праздный, мне интересно, какие потребности возникают у тех, до кого я что-то пытаюсь донести.

Хорошая книга

Хорошая книга для первого раза, но все таки от едких коменнтариев по поводу СТЛ можно было бы воздержаться. Еще можно было бы добавить в соответсвующие места ссылки на "первоисточники" Cатера, Мейерса... (например почему не надо перегражет приведение по типу и т.д.) И ессно уже С++11 на дворе, хотя я подозреваю, что автор скажет несколько нелестных слов о новомо стандарте.

Ага, щас

Ну вы там свою книжку тогда напишите с блэкджеком и шлюхами и в ней воздерживайтесь от чего хотите, а мне не надо рассказывать про достоинства STL, моё мнение по поводу этого бастарда окончательно и пересмотру не подлежит — как, впрочем, и относительно людей, которые не понимают, почему STL именно бастард, а не что-то иное. Я, кстати, не понял, какой "первый раз" имеется в виду, книжка-то, между делом, выдержала три издания, и у меня она не первая и не единственная.

Под первоисточниками лично я привык понимать ровно те материалы, которые использованы при подготовке текста, и никакие иные. В данном случае Мейерс и кого вы там ещё упоминаете — в число "первоисточников" не входят, я вообще не считаю нужным тратить время на чтение "современных" книжек по C++ (последняя книжка, прочтение которой не было пустой тратой времени — это "дизайн и эволюция", но, естественно, старого издания, ещё до начала STL-ной эпохи), а "почему не надо использовать операцию преобразования типа" — вынесено из личного опыта.

По поводу очередного поделья "стандартизаторов" я тоже уже высказывался, повторяться смысла не вижу.

первый раз

Андрей, для первого раза, я имел ввиду для начинающих. А по поводу stl и с++11 с вами многие не согласятся. Я только соглашусь, что из-за всех нововведений и без того сложный язык,
стел еще сложнее для эффективного использования.
В чисто вычислительных задачах на кластерах до сих пор используется фортран, с++ претендует на нечто большее, и дает много новых возможностей, которые не обязательно использовать.
Например, если мне нужен hash map, у меня нет желания подключать стороние библитотеки или писать его самому пока это не будет критическим. Или как написать операторы сложения матриц без копирования временных обьектов (a+b+c) без rvalues& или expression templates? Конечно, из-за нагромождения всяких бесполезных структур данных с++ программа может начать работать медленее чем на скала (так случилось на моем лаптопе с кодом из http://research.google.com/pubs/pub37122.html). Но это уже квалификация разработчиков - не надо микроскопом забивать гвозди. В целом, спасибо за книгу.

Конечно, не согласятся

Андрей, для первого раза, я имел ввиду для начинающих.

Принято.

А по поводу stl и с++11 с вами многие не согласятся.

Многие? Я больше скажу: со мной не согласятся практически все, кто C++ увидел после 1999 года (или 1995, если речь идёт об англоязычных программистах), и многие из тех, кто C++ увидел раньше. При этом всех этих "несогласных" можно поделить ровно на две части: (1) те, кто пишут на C++ (с использованием STL и прочих примочек) и (2) те, кто на C++ больше не пишут, потому что "это просто мрак какой-то".

При этом если мы разделим программистов, знающих (но не обязательно использующих) C++, по другому признаку, а именно — на людей, разборчивых в выборе средств, и на тех, кто плевать хотел на грамотный выбор инструмента, лишь бы быстро сляпать, чтобы как-то работало — то получим ровно те же самые две категории людей. Те, кто в выборе средств не разборчив, используют C++ в связке с STL. Те, кто разборчив, в большинстве своём просто уходят из C++ на другие языки, кто-то "вверх", на питон, например, или на Java, кто-то "вниз", на plain C, причём часто даже ANSI C. Замечу, мне часто приходится видеть ООП на чистом С в исполнении таких людей, они моделируют наследование, вручную строят таблицы виртуальных функций и т.п., но о возврате к C++ при этом даже не помышляют, ибо весь этот кошмар с STL'ем, RTTI и прочими примочками — ну, кошмар и есть кошмар.

Остаётся ещё очень малочисленная группа людей, разборчивых в средствах, но при этом понимающих, что C++ сам по себе — инструмент неплохой, если не считать STL и всякие Boost'ы имманентной принадлежностью "C++-программирования" и если быть готовым, например, к --disable-rtty и отказу от исключений. К этой последней группе принадлежу, собственно, я, и я очень надеюсь, что эта группа пополняется за счёт моих учеников и читателей моей книжки.

Например, если мне нужен hash map, у меня нет желания подключать стороние библитотеки или писать его самому пока это не будет критическим.

Ну так пишите на Java или на Питоне, кто мешает? Зачем вам C++, если вы готовы одним махом (подключением STL) угробить все его достоинства?

. Или как написать операторы сложения матриц без копирования временных обьектов (a+b+c) без rvalues&

Как-как, известно как — сделать отдельно объект реализации этой матрицы со счётчиком ссылок и copy-on-write.

Конечно, из-за нагромождения всяких бесполезных структур данных с++ программа может начать работать медленее чем на скала [...] Но это уже квалификация разработчиков

Вы одну простую вещь поймите — это не разработчики виноваты, это вот так вот на мышление программиста действует этот монструозный конгломерат. То есть если быть неразборчивым в средствах, то в результате такая вот "низкая эффективность" будет лишь одним из неизбежных негативных последствий. Ну а человек, разборчивый в средствах, STL применять не станет.

не надо микроскопом забивать гвозди.

Забивание гвоздя микроскопом начинается в тот момент, когда использовано ЛЮБОЕ имя из namespace std. Коготок увяз — всей птичке пропасть.

В целом, спасибо за книгу.

Пожалуйста, мне не жалко. А вам она зачем, если не секрет? Вы на перворазника вроде не похожи.

Файлы к книге

А где же скачать обещаные тексты примеров программ, приведённых в книге?

Ой

И вправду нету. Надо сказать, за три года вы первый, кто это заметил :)

Я постараюсь эту ситуацию исправить в ближайшее время; вас что-то конкретное интересует? Если скажете, с чего начать, с того я и начну.

UPD: Основные примеры выложены, если интересует что-то ещё — пишите.

очепятка?

стр. 82, char* FileException::strdup:
char *res = new[strlen(str)+1];
-> char *res = new char[strlen(str)+1];

не ?.. на первый вариант gcc (4.7.2) ругается: expected type-specifier before «[»

Спасибо!

Совершенно верно, это опечатка (что характерно, как я сейчас посмотрел, она есть во всех трёх версиях книги, живучая попалась). Спасибо за её выявление, теперь есть шанс, что в следующем издании её не будет.

Const

Здравствуйте!

На стр.57 возможно за место MyInt operator++(int) {/*...*/} стоит написать const MyInt operator++(int) {/*...*/}, чтобы, например, не было такого:
MyInt test(4);
test++ = 16;

За книжку большое спасибо!

век живи, как говорится

Вот ей-богу, до сего момента я был уверен, что значение (если оно не ссылка) леводопустимым не будет и так. Заметим, если функция возвращает обычный int, то присваивание применить не получится. Стало быть, для классов сие правило не работает.

Кошмарная штука этот C++, если подумать.

Точно

Про встроенный тип это да). Но ведь компилятор создает временный объект, при возврате из функции (метода), и получается, что с этим объектом можно работать как и с любым другим. Ужас)))

временный объект, ага

Вот то-то и оно, ведь временные и анонимные объекты даже нельзя передавать по неконстантной ссылке (вне всякой зависимости от их собственной константности), именно из тех соображений, что они по смыслу не должны быть леводопустимыми.

Судя по тому, что мы тут видим, this — не ссылка, а указатель, и по нему временные объекты передавать, видимо, можно. Я фигею от этой семантики.

this

Здравствуйте!

Не совсем понял о чем здесь речь.

Судя по тому, что мы тут видим, this — не ссылка, а указатель, и по нему временные объекты передавать, видимо, можно

Можно поподробнее? Просто мы говорили об этом:

MyInt operator++(int) {MyInt tmp(*this); i++; return tmp;}

По указателю ничего не передается. Или я что-то не так понял?

Да уж, не поняли

Начать с того, что тело операции ++ никак не может оказать влияние на то, как её можно, а как нельзя вызывать. Тело и вызов вообще могут быть в разных единицах трансляции.

А по указателю передаётся объект при вызове операции ++. И речь здесь о том, что, оказывается, временный/анонимный объект можно передавать в его методы по неконстантному this, что, мягко говоря, неожиданно, особенно с учётом того, что передавать временные/анонимные объекты по неконстантным ссылкам нельзя, и это объясняется так, что неконстантная ссылка по смыслу — выходной параметр, а временные и анонимные объекты по смыслу — не леводопустимые (то есть как бы константы, хотя и не const).

Не компилируется

"Исходный текст примера MultiMatrix из последней главы" не компилируется

multimatrix.cpp: In member function ‘T& MultiMatrix::operator[](unsigned int) [with T = int, T init_val = -0x00000000000000001]’:
multimatrix.cpp:67:21: instantiated from here
multimatrix.cpp:60:28: error: ‘class Array’ has no member named ‘Elem’

Спасибо!

Там действительно какая-то странная версия оказалась, частично исправленная, частично нет. Я выложил исправленный вариант, можете попробовать.

Преобразование указателей

Спасибо большое за книгу!
Когда читал, одна вещь вызвала серьезные затруднения для понимания. Меня мучил такой вопрос: будет ли при private наследовании работать неявное преобразование указателей от указателя на наследника к указателю на предка? Я проверил и убедился, что не будет. На странице 90 есть фраза о том, что есть случаи, когда тот факт, что один класс унаследован от другого сам по себе является деталью реализации, но дальше в книге говорится только о защите методов и полей, а о преобразовании указателей не упоминается. Нельзя ли внести несколько слов в книгу о таком эффекте private наследования?

приватное наследование

Дело в том, что вы не совсем правы. Неявное преобразование указателей будет работать там, где разрешено использование знания о том, что унаследованный класс является наследником своего предка. Например, если сделать некую функцию "другом" наследника, то внутри этой функции преобразование по закону полиморфизма работать будет: этой функции _разрешено_ знать, что наследование имеет место. То же самое будет происходить и, например, в методах наследника, включая статические — там это знание тоже разрешено.

В принципе, это напрямую следует из того, что сказано в книжке, но вообще я подумаю на тему отдельного замечания в этом плане.

Тут ещё такой момент есть, что в реальной жизни приватное наследование никогда не применяется — я, во всяком случае, ни разу с таким не сталкивался и с трудом представляю себе ситуации, когда оно зачем-то может понадобиться; ну а объём книжки хотелось бы сохранить небольшим. Есть ведь и более серьёзные вещи, которые в книжке полностью обойдены вниманием: namespaces, например, или множественное наследование, или там указатели на метод класса, да ещё много чего.

Опечатка

Страница 103, нижняя половина. Абзац начинается так:

Когда переменная scene_lenght...

Спасибо!

Болшое спасибо, эту опечатку вы заметили первым. Я пометил её в своём экземпляре, так что если дойдёт дело до четвёртого издания, там опечатка будет исправлена.

Опечатка?

Андрей Викторович, возможно, на стр. 6 в сноске опечатка
"Любителям громких заявлений ОТ неотделимости стандартной библиотеки..."

точно

да, вы правы, спасибо

Вообще-то...

Вообще-то, не раз случалось в течение жизни брать в руки какую-либо толстожопую книжку по "плюсам" с немалым желанием извлечь из неё нечто для себя нужное. Что-то как-то никогда сильно не шло... Давно уже принял для себя, что "по жизни" мне и Си - за глаза и за уши, максимальная по размеру программа не превышала десяти тысяч строк. "Плюсы" устойчиво ассоциировались с инструментом, необходимым лишь для проектов требующих десятков и сотен программирующих особей и задач, близких к космическим.
Однако, уже несколько самых первых строк Вашей книжки несколько изменили точку зрения. Аж с момента представления элементарной структуры, куда (надо же!) можно запихать относящуюся к ней функцию. Прямо не отходя от кассы взял свою же уже довольно старую программу и попробовал переписать. Интересные ощущения! Заместо висящих где-то функций, вдруг получилось нечто куда более структурированное и куда более понятное. А если верить, что "машинный код" от этого действа не изменяется, это совсем не так уж плохо! То есть, один "плюс" - уже налицо. За "второй", покамест, ничего сказать не могу. Поживём, увидим, может и приспособятся куда-нибудь эти самые "плюсы" со временем... Но по любому, написано так, что перевода с русского на русский не требует. Так что, однозначно, книжка пользователя имеет. Дело за малым - чтобы попала она в руки этому самому пользователю, который с полок магазинов сметает нечто куда более ненужное. Хорошее введение. Нужное.
Ну, а порадовавшие меня (чисто из общих и стилистических соображений!) штрафные в сторону ворот Степанова сотоварищи, наверно, тех, кто давно в "плюсах", порадовать и не могли - STL им нужен хотя бы уже потому, что спрашивать их при приёме на работу не будут не то, что о каких-то предпочтениях, но даже и о языке. На каком скажут, на таком и писать будут.
В общем, Введение хорошее. Спасибо.

ЗЫ Капча у Вас тоже неплохая, чёрт возьми...

Спасибо :) А за

Спасибо :) А за капчу прошу прощения, без неё у меня руки устают спам стирать.

Насчёт машинного кода -- к сожалению, он не изменится только лишь в случае, если мы при компиляции выключим поддержку оработки исключений. В противном случае ради этих пресловутых исключений компилятор плюсов в начало и конец каждой функции запихивает кучу всего очень страшного.

Вставлю и свои

Вставлю и свои пять копеек.
На рутрекере видел эту книжку. Выложил кто-то. Так там к ней один из комментаторов отписал что-то навроде: "В книге используется stdio.h вместо iostream. Для кого автор пишет эту ерунду?". Честно говоря, настолько каким-то глупым и даже провокационным показался этот коммент (а не сам ли автор написал такое?!), что не поленился и скачал. Как выяснилось, книгу эту я уже видел. За издание точно не скажу (может, и не третье), но помню, что впечатление она оставила хорошее. Почему сюда и зашёл, на рутрекере отписываться просто смешно. И как оказывается, тут ещё и новые книги появились. А почему понравилась? Да потому, что она в отличие от многих книг по С++, ставящих всё с ног на голову, излагает языком точным, и совершенно очевидно, что автор ПОНИМАЕТ то, о чём говорит. Даются основы языка С++. Причём именно языка! А что ещё должно быть в книге, озаглавленной "Введение в С++"? И точно указан контингент - учащиеся, знающие язык Си. Всё пристойно, в рабочем режиме. Может, сравним с каким-нибудь другим учебником? Например, с учебником С++ Дятела? Что мы там имеем? Многотонный фолиант (на ногу уронить - пиши, пропало!), начинающийся с полюбившегося некоторым iostream'ного cout, выводящего "Hello, world". Разумеется, никакого предварительного знания языка Си не требуется, поскольку по заверению авторов, "он и сам собой изучится" по ходу пьесы, так что будете знать аж два языка! По довольно тщательному (размерно!) описанию циклов, условий, основных конструкций, становится очевидным, что авторы на полном серьёзе считают, что можно плюсам обучить с нуля! А язык-то, для профессионального пользователя! Программист - это профессия, которой учатся. Не один год. То есть, потенциальный читатель каким-то сверхъестественным образом (видимо, уже при рождении) должен знать с десяток-другой сопутствующих дисциплин. Не смешно? И кстати, если это всё-таки не так, зачем нужен С++ этого самому потенциальному читателю? Знание основ программирования на сегодняшний день - обязательное условие "общей" грамотности. Но не С++ же! Существует куча очень даже приличных языков, позволяющих как быстро освоить, так и успешно использовать их в решении своих проблем пользователям без специальной подготовки. А они читают книжку Дятела, который обещает (как и многочисленные курсы) не только знание языка С++ после завершения "обучения", но и всякие "высокооплачиваемые работы" не без блекджека! То есть, попросту теряют время. Или, может, Дятел этого не знает? Вообще-то, любой человек пишущий по теме "++" не может не являться профессиональным программистом! Стало быть, врёт? Ага! "Маркетинг" по-импортному называется, "мошенничество" по-русски. Кидалово. И благо бы был один такой Дятел, так их - просто полки магазинные ломятся! Так что, в печку всех этих дейтелов, в печку... Вслед за Каутским. Писал бы Булгаков в наши дни, его Швондер однозначно бы был автором учебника по плюсам. И ничуть дела не меняет то обстоятельство, что взявший эту книжку программист найдёт в ней что-то для себя полезное. На то он и программист - он уже умеет читать селективно и в состоянии грепнуть из текста именно то, что ему нужно. А остальное куда? Кстати, для программистов уже состоявшихся существует специальная литература. Максимум, во что может превратиться человек после чтения таких дейтелов, это (кто-то сверху, правда, сказал - "обезьяна", но будем гуманней к несчастным) девочка Маша (сходу такой образ нарисовался), которую взяли кладовщицей на громадных размеров складской терминал с кучей складов-контейнеров, где она ничего не знает, ни где чего лежит, ни для чего оно предназначено. Только что - молодая, бегает быстро! Вот только попроси эту Машу принести какой-нибудь инструмент, пригодный, скажем, для лесозаготовки, то она (поискав с полдня) садовые ножницы и принесёт. Здрасьте! А пройдут годы, поднаберётся опыта? Ну, станет бабой Машей, с тремя радикулитами, ковыляющей между своими контейнерами со скоростью в полузла, но зато прекрасно знающей что лежит в каком контейнере. Вот только попробуй опять собраться куда-нибудь лес попилить, да порубить, она тебе принесёт те же садовые ножницы, что и много лет назад...
Чего-то меня понесло... В общем, повезло тем читателям Столярова, кто на сегодня - студент. Слушай, что взрослый дядя говорит, да делай. Всего делов! Кстати, и не только студентам почитать-то можно - кто-то сверху очень правильно отметил, что изложение просто мозгинаместоставящее. У всех есть где-то какие-то пробелы, а текст "Введения в С++" достаточно короткий, чёткий и вменяемый. Ничуть не удивлюсь, если и обычный пользователь, для своих нужд уверенно пользующий какие-нибудь перлопитоны и работающий где-нибудь в отделе персонала, тоже вполне может поиметь что-то полезное - уж во-всяком случае, при приеме на работу "программиста", аналогичного рутрекеровскому любителю иостримов, вполне самостоятельно сможет поставить правильный диагноз и чётко отработать указателем на объект Двери, не отвлекая от работы людей, занятых программированием.

Писал бы

Писал бы Булгаков в наши дни, его Швондер однозначно бы был автором учебника по плюсам.

Как говорят англоязычные товарищи, you made my day :-) Вот прямо в рамочку и на стену.

Ну и вообще спасибо за отзыв, не каждый день такое. А коммент тот на трекере я видел, да мало ли таких комментов в интернете.

опечатка?

Добрый день, уважаемый Андрей Викторович.

Большое спасибо за замечательную книгу! Использую её в своей практике для обучения студентов, очень помогает.

Замечена опечатка на стр. 68. Вместо этого:
int A::the_static_field = 0;

надо, по всей видимости, писать так:
int Cls::the_static_field = 0;

Большое спасибо!

Действительно ошибка в тексте, и до вас её никто не замечал, то есть ещё бы немножко — и она ровно в таком виде оказалась бы в тексте четвёртого тома "Введения в профессию". Так что я вам очень признателен за сообщение.

Опечатки?

Добрый день!

Когда комментировал в прошлый раз не все разглядел. Возможно, это тоже опечатки.

1) Опечатки на странице 69.

Вместо:
A a;
a.the_static_field = 15; // правильно
A::the_static_field = 15; // тоже правильно

должно быть так:
Cls a;
Cls.the_static_field = 15; // правильно
Cls::the_static_field = 15; // тоже правильно

В тексте абзаца выше тоже есть упоминание необъявленного класса A (четвёртая строка сверху).

2) На странице 82 в статическом методе strdup класса FileException вместо:
char *res = new[strlen(str)+1];

должно быть:
char *res = new char[strlen(str)+1];

Было такое

В ныне существующей версии рукописи (которая пойдёт в 4 том) всё это уже исправлено, только что проверил. Но всё равно большое спасибо!

Отправить комментарий

Содержание этого поля является приватным и не предназначено к показу.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Доступны HTML теги: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <pre>
  • Строки и параграфы переносятся автоматически.

Подробнее о форматировании

CAPTCHA
Проверка на бота
Image CAPTCHA
Copy the characters (respecting upper/lower case) from the image.