LINUX.ORG.RU

Какую книгу по C++ выбрать?

 ,


5

2

Какую книгу по с++ выбрать

  1. Герберт Шилдт. C++ для начинающих. Шаг за шагом
  2. Стивен Прата. Язык программирования C++. Лекции и упражнения
  3. Предложите свой вариант (учил джаву, с++ смотрел видео ну можно сказать не с нуля учу)

Перемещено hobbit из general

Ответ на: комментарий от bugfixer

Покажите мне этот сегфолт. Хинт: capacity != size, нужно сильно постараться чтобы этот memwrite чужую память попортил.

Хм.

#include <iostream>
#include <vector>
#include <csignal>

int i;

void signalHandler( int signum ) {
//Обработчик SIGSEGV
   std::cerr << "Segmentation fault detected!" << std::endl;
   std::cerr <<  "i = " << i << std::endl;   
   std::exit(signum); 
}
 
int main(void)
{

    std::signal(SIGSEGV, signalHandler);
    
    std::vector<int> v = { 1, 2, 3};
    i = v[v.size()-1];
    while (i++)
    {
       v[i]=i; //Ждем когда вывалится с исключением.
    }
    return 0;
}

Запускаем:

$ g++ -o segf segf.cpp
$
$ ./segf
Segmentation fault detected!
i = 15444

Похоже за размер стека перевалило.

praseodim ★★★★★
()
Ответ на: комментарий от LamerOk

А современность С++ погоды в целом не делает в этом вопросе вообще никакой.

Делает и еще какую. Тот же auto отлично скрывает страшные имена типов итераторов, например. А auto в качестве типа возвращаемого значения позволяет возвращать типы, которые вручную бы заманался выписывать (а в случае с возвратом лямбд это вообще было бы невозможно).

C++98 уже разительно отличался от C++ с которого я начинал в 1992-м. А C++11 еще более. Чем дальше, тем больше приходится пользоваться именно концепцией итераторов, а не указателями.

Например, я вот честно ХЗ зачем здесь пример кода на C#, но попробуйте его применить к контейнеру, который хранит элементы последовательно, но не в одном непрерывном векторе, а в наборе чанков. В C++ можно сделать контейнер, который выставляет наружу итераторы и тот же std::lower_bound будет с ним работать.

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

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

eao197 ★★★★★
()
Ответ на: комментарий от eao197

я вот честно ХЗ зачем здесь пример кода на C#,

Обобщённый алгоритм в языке, где нет никакой адресной арифметики.

Ну так давайте разберем какие-то конкретные примеры.

Я выискивать из прода щас ничего не буду, возьму простейший пример даже без параметризации форматом матрицы:

struct img
{
    size_t width;
    size_t height;
    unsigned char *data; // BGR
};

extern void f(size_t x, size_t y, unsigned char r, unsigned char g, unsigned char b);

void process_bitmap(struct img &img)
{
    for(size_t y = 0; y < img.height; y++)
    {
        for(size_t x = 0; x < img.width; x++)
        {
            unsigned char *p = img.data + img.width*3*y + x*3;
            f(x, y, p[2], p[1], p[0]);
        }
    }
}

как это эффективно сделать без адресной арифметики и алиасинга?

LamerOk ★★★★★
()
Последнее исправление: LamerOk (всего исправлений: 1)
Ответ на: комментарий от LamerOk

unsigned char p = img.data + img.width3y + x3;

тут явное общее подвыражение. вы плюсуюете каждый раз img.data, вычисляете указатель на начало строки

img.data + img.width3y

эта лабуда не меняется при цикле по х. и умножение x*3 избыточно.

у настоящих посонов цикл по x должен выглядеть так:

unsigned char* p  = img.data + img.width*3*y; ///начало
unsigned char* pp = p + img.width*3; ///конец
while ( p < pp) {
  f(x, y, p[2], p[1], p[0]);
  p += 3; 
}

про оптимизацию компилятором слыхал. но не факт что он раскрутит. это надо на годболте смотреть

alysnix ★★★
()
Ответ на: комментарий от LamerOk

Обобщённый алгоритм в языке, где нет никакой адресной арифметики.

Выясняется, что он обобщенный только для типа в последовательности, но не для самой последовательности. Т.е. не такой уж и обобщенный.

как это эффективно сделать без адресной арифметики и алиасинга?

Хороший пример. Но зачем для этого знать Си и почему нельзя это разбирать сразу в C++? В Си какая-то другая адресная арифметика?

eao197 ★★★★★
()
Ответ на: комментарий от praseodim

Какого ещё стэка?

Показалось, что небольшая переменная на стеке размещена

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

LamerOk ★★★★★
()
Ответ на: комментарий от eao197

Обобщённый алгоритм в языке, где нет никакой адресной арифметики.

Выясняется, что он обобщенный только для типа в последовательности, но не для самой последовательности. Т.е. не такой уж и обобщенный.

С чего бы? Оператор [] прекрасно переопределяется. Код из примера выше почти полная копия std::binary_search. Чтобы сделать его полной копией достаточно добавить функцию - компаратор.

Это пример того, что в этом объёме выразительные возможности C# и C++ практически идентичны. Разница между ними, конечно, есть, но уже в других деталях.

Но зачем для этого знать Си

Мы уже ушли с этого вопроса на вопрос "а зачем вообще нужна адресная арифметика?".

LamerOk ★★★★★
()
Ответ на: комментарий от LamerOk

С чего бы?

А разве прототип метода не указывает прямо на тип входной последовательности?

public int FindIndex(T[] sortedData, T item)

Мы уже ушли с этого вопроса на вопрос «а зачем вообще нужна адресная арифметика?».

Может покажете место, где это произошло, потому что я не помню чтобы где-то утверждал, что адресная арифметика не нужна.

В современном C++ дело с ней приходится иметь реже, чем раньше (мне, например, в своей работе очень редко). Но под сомнение я эту часть C++ не ставил.

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

v[v.size()] = 0;

полностью эквивалентна записи:

*(v.begin() + v.size()) = 0;

И в таком варианте она применима не только к std::vector, но и к другим типам, например, к std::deque.

Т.е. чтобы объяснить изучающему C++ суть проблемы в этом случае не нужно опускаться на уровень адресной арифметики.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

запись: v[v.size()] = 0; полностью эквивалентна записи: *(v.begin() + v.size()) = 0;

И в таком варианте она применима не только к std::vector, но и к другим типам

У других типов может быть другая семантика оператора []

#include <map>
void test() {
    std::map<size_t, int> list;
    auto begin{ list.begin()};
    // begin + list.size(); // ??
    list[list.size()];
}
vM ★★
()
Ответ на: комментарий от vM

Когда я писал «И в таком варианте она применима не только к std::vector, но и к другим типам», то речь шла именно о записи:

*(v.begin() + v.size()) = 0;

Кроме того, «она применима не только к std::vector, но и к другим типам» не означает, что применима ко всем другим типам.

Так что решительно непонятно что именно вы хотели сказать своим комментарием.

eao197 ★★★★★
()
Ответ на: комментарий от vM

С чего бы?

А разве прототип метода не указывает прямо на тип входной последовательности?

Ровно в той же, что мере, что и std::binary_search - обобщённая функция принимает на вход контейнер элементов шаблонного типа T и элемент шаблонного типа T, который ищет в контейнере. Шаблонный тип T должен удовлетворять интерфейс IComparable - это полный аналог наличия оператора std::less для C++, с той только разницей, что в случае ошибки вместо загадочной простыни на 1000 строк про отсутствие оператора в месте вызова тут будет выдана корректная ошибка.

LamerOk ★★★★★
()
Ответ на: комментарий от LamerOk

Ровно в той же, что мере, что и std::binary_search

Вы точно уверены на счет «принимает на вход контейнер»?

https://en.cppreference.com/w/cpp/algorithm/binary_search.html

Я не знаток C#, но разве запись T[] означает произвольный контейнер с наличием оператора []?

eao197 ★★★★★
()
Ответ на: комментарий от LamerOk

А что ещё она может означать?

Что-то вроде аналога C++ного span, т.е. непрерывную последовательность из N элементов.

Повторюсь, я не знаток C#, но неужели T[] – это эквивалент произвольного IEnumerable?

eao197 ★★★★★
()
Ответ на: комментарий от eao197

неужели T[] – это эквивалент произвольного IEnumerable?

T[] - это экземпляр класса array параметризированый шаблонным типом T. Такой класс может быть создан пользователем через indexer - я же выше писал:

Оператор [] прекрасно переопределяется.

Array реализует несколько интерфейсов, среди них и IEnumerable, так что, да, одномерный T[] может быть использован везде, где используется IEnumerable.

LamerOk ★★★★★
()
Ответ на: комментарий от LamerOk

А зачем?

Я это к тому, что если бы у вас в примере было:

int FindIndex(IEnumerable<T> sortedData, T item)

То это было бы более похоже на C++ный std::binary_search. А так сравнение не равноценное.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Сишарпный IEnumerable<T> в переводе на сиплюсплюснотый язык - это прямой итератор чтения / записи без произвольного доступа. В столь любимом вами "современном С++" это комбинация трейтов input_iterator / output_iterator / forward_iterator.

А для бинарного поиска нам нужен трейт random_access_iterator, что в сишарпе предоставляется оператором [].

LamerOk ★★★★★
()
Последнее исправление: LamerOk (всего исправлений: 1)

С плюсами такая штука - читай всё, что попадётся под руку. Язык довольно разлапистый, и для нормального знакомства потребуется не одна книжка. Классики: Страуструп, Мейерс, Йосутис. Если что-то непонятно, спрашивай у chatGPT, и проверяй ответы экспериментально. И Шилда, и Прату бери, нос не вороти. Отзывы в инете читай, но учти, что люди частенько хотят идеальных книг, а такого не бывает.

seiken ★★★★★
()
Последнее исправление: seiken (всего исправлений: 1)
Ответ на: комментарий от seiken

Вот я, например, сейчас читаю классическую механику, Cambridge press, казалось бы не хухры-мухры, книга 2006г., 6я перепечатка. И там во вводной части о тройном векторном произведении, как минимум в одном месте такая чушь написана, что впору этот кэмбридж пресс использовать для розжиги печки. И это естественнонаучная дисциплина. Что же говорить о интеллектуально менее развитых «специалистах по программированию»…

seiken ★★★★★
()
Ответ на: комментарий от eao197

Так в этом и фокус хорошего обучения, чтобы небольшим количеством небольших упражнений достичь правильного навыка.

Это не работает даже для обучения сложению. Да, на пальцах с записью итога в тетрадку в клеточку гусиным пером. Прежде чем у пенька с глазами арифметика становится не требующим размышления почти безошибочным навыком, пенёк решает сотни (для «удочки»), а то и тысячи (для «превосходно») простейших упражнений.

Вы же тут обсуждаете про научению ЯЗЫКУ. Вспомните, что РОДНОЙ язык на достойный уровень владения учат 15 лет с АГРОМЕННОЙ кучей «чтения и написания кода». Но овладевают им не только лишь все.

«Теория без практики мертва» – абсолютная истина при изучении ЛЮБОГО языка, от математики и латыни до Rust или Common Lisp. Чтобы научиться писать на ЯП, необходимо научиться ДУМАТЬ на этом языке, что невозможно без его использования.

Как пара диалогов на каждое грамматическое правило не позволит вам свободно владеть эрзянским, так и пара написанных примеров на каждый оператор/библиотечную функцию/т.п. C++/Rust не научат писать на нём произвольные программы.

mister_VA ★★
()
Ответ на: комментарий от eao197

Нет, до С++ не добрались, я создавал курсы по физике и Паскалю. Но изучал множество пособий по… х.з. чему. Самые лучшие были посвящены описанию ЯП, но вы понимаете, что описание ЯП вовсе не учебник по программированию на этом ЯП?

Дело в том, что изучив уже половину такого талмуда, ты так и не понимаешь, как на этом ЯП сделать хоть что-то вполне элементарное. Ну там числа Фибоначчи, квадратное уравнение с произвольным дискриминантом, двойной факториал… Зато тебе пытаются разъяснить, что такое побочные эффекты у функций или как умножать числа арифметическим сдвигом.

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

mister_VA ★★
()
Ответ на: комментарий от mister_VA

Дело в том, что изучив уже половину такого талмуда, ты так и не понимаешь, как на этом ЯП сделать хоть что-то

Отучаемся говорить за всех (с)

Вы отождествляете «обучение» и «освоение», при этом говорите именно об «освоении», на которое, действительно, уходит много времени и труда.

Тогда как у «обучения», особенно если это какие-то курсы с преподавателем, всегда есть жесткие и, как правило, небольшие временные рамки. Грубо говоря, за семестр или два (если речь о ВУЗе) нужно дать студентам C++ (или Java, или C#, или еще что-то).

И в «обучении» на первый план выходит то, как за небольшое время и небольшое количество практических занятий привить людям полезные привычки. Касательно C++ это будут навыки применения RAII, навыки использования ООП с классами/наследованием, навыки использования обобщенного программирования (это нужно чтобы люди научились различать где выгодно применять ООП с классами и объектами, а где функции, в том числе и обобщенные).

Если у вас есть роскошь вести группу обучающихся C++ в течении 2-3-4-х лет, да еще на хорошем большом проекте – ваше щчасте. Но я не верю, что где-то в жизнь воплощена такая фантастика.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Вы отождествляете «обучение» и «освоение»,

Обучение означает овладение ЗУНами по предмету изучения, где З – знания, У – умения, Н – навыки. Вы под «обучением» подразумеваете даже не З, а озвучивание некоего набора информации об.

всегда есть жесткие и, как правило, небольшие временные рамки. Грубо говоря, за семестр или два (если речь о ВУЗе) нужно дать студентам C++ (или Java, или C#, или еще что-то).

Это чистой воды профанация, в которую не впихнуть ваши ///Касательно C++ это будут навыки применения RAII, навыки использования ООП с классами/наследованием, навыки использования обобщенного программирования… Какое обобщённое программирование и ООП на С++ студентам, которые на отеб* делали домашку по информатике, где на программирование отводится 10 – 20 часов в год в виде «программирования» на Питоне в LO. Но для технических ВУЗов обычно отводят 6 семестров на программирование.

Если у вас есть роскошь вести группу обучающихся C++ в течении 2-3-4-х лет, да еще на хорошем большом проекте – ваше щчасте. Но я не верю, что где-то в жизнь воплощена такая фантастика.

И напрасно, я как-то читал руководство по программированию на Си, созданное юсовким профессором на основе его курса, где он несколько лет «учил» студентов Си на примере создания программы управления лифтом в многоэтажном здании. Имеет ли такой подход смысл, учитывая, что первую половину курса студенты писали проги, которые не принимали никаких входных данных и не выдавали никаких результатов, я не знаю.

«Овладение языком через языковую практику» вовсе не мой индивидуальный бзик, даже в этой теме такой подход несколько раз озвучивался. В нём, конечно, различаются 2 парадигмы: читать хорошее или писать самому. Касаемо С/С++, я вообще встречал предложение от одного из создателей gcc, что лучший способ выучить Си – это читать его стандарт и смотреть исходники, как это реализуется в компиляторе.

mister_VA ★★
()
Ответ на: комментарий от mister_VA

Учить синтаксис не имеет смысла.

В зависимости от целевой группы программа обучения будет разной.

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

Для инженеров это все не подходит от слова совсем. Инженерам хорошо заходит программирование микроконтроллеров. STM для тех, то хочет потом этим заниматься, Arduino для тех, кому нужно просто понимать что за этим стоит, и которые программировать профессионально не планируют.

Соответственно, книги надо подбирать под это.

Но если быть более конкретным, то книги редко предполагают замену курса. Я таких книг встречал очень мало в своей жизни, вне зависимости от предмета.

Книга обычно это справочник, который помогает найти ответы на то, что не понял на занятиях. Поэтому книги по синтаксису, по концепциям (RAII, …), по паттернам, по алгоритмам и пр. существуют и полезны для прочтения. Но это не замена курсу, это помощь в освоении курса, который ведет преподаватель. К сожалению, препода из обучения не исключить, точнее исключить можно, но тогда время освоения увеличится раз в 10, плюс появится много критических пробелов. Хороший препод ведет студента учитывая его скорость освоения и его интересы, книга в этом не заменит его никак. Кроме того, каждый ВУЗ уникален, даже программы в ВУЗах часто уникальны в том смысле, что собирают абитурьентов с разным мировоззрением, с разными целями, поэтому на каждой программе хороший курс по С++ будет сильно отличаться друг от друга.

Короче, вопрос ТС по факту не имеет смысла, но если книга все же нужна, то открываешь либрусек или идешь в книжный магазин и листаешь книгу минут 5, если зашла – читаешь, если нет – берешь следующую с полки..

soomrack ★★★★★
()
Ответ на: комментарий от mister_VA

Вы что мне пытаетесь доказать?

Что на овладение языком программирования нужно время и труд?

Так я с этим и не спорил.

Что «обучение» языку, которое ограничено временем и объемом учебных задач – это профанация?

eao197 ★★★★★
()
Ответ на: комментарий от soomrack

Но если быть более конкретным, то книги редко предполагают замену курса.

Таки это так и об этом я писал в разных темах здесь. Вот только и вузовские курсы разные бывают. Например, по Common Lisp мне попадались лекции, описывающие сам язык, т.е. бесполезные, поскольку справочников и дотошных описаний Лиспа достаточно.

Хороший препод ведет студента

Вы понимаете, что на потоковой лекции от ста до пятисот студентов? И все с разным уровнем… вообще всего, от исходных знаний до скорости мышления?

Короче, вопрос ТС по факту не имеет смысла

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

mister_VA ★★
()
Ответ на: комментарий от eao197

Дайте, пожалуйста, ссылку на учебный курс по какому-то из языков программирования, расчитанный на 2 года.

Мат-мех ЛГУ им. Жданова. Нас учили Паскалю 3 года.

P.S. И совершенно напрасно потратили дорогое для всех время.

P.P.S. В матклассе я учился Фортрану 2 года, хотя первые полгода была пропедевтика из булевой алгебры, алгебры контактных схем, систем счисления, а последнее в полугодие мы неожиданно получили доступ в лабораторию с Паскалем 5.5 и забили на Фортран.

mister_VA ★★
()
Ответ на: комментарий от mister_VA

Мат-мех ЛГУ им. Жданова. Нас учили Паскалю 3 года.

Это какой год выпуска и какая программа? Мне в принципе сложно представить, чтобы когда-то на матмехе учили 3 года ЯП. Это могло быть разве что только на матобесе, но там Паскаль у Терехова 3 года звучит как оксюморон.

soomrack ★★★★★
()
Ответ на: комментарий от mister_VA

Хороший препод ведет студента

Вы понимаете, что на потоковой лекции от ста до пятисот студентов? И все с разным уровнем… вообще всего, от исходных знаний до скорости мышления?

Ну до 150 я прекрасно понимаю, про 500 на программирование это у вас фантазии какие-то… На матмехе в петергофе есть только одна аудитория (01), которая может вместить 500 человек, и то не факт, что 500 влезет, а в своей жизни я ее заполненной видел только два раза.

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

soomrack ★★★★★
()
Последнее исправление: soomrack (всего исправлений: 2)
Ответ на: комментарий от soomrack

Это какой год выпуска и какая программа?

Матобес имел совсем другую программу, а я про очень обычных будущих математиков. Год выпуска понятен по «им. Жданова» (я плохо помню даты, но это вроде 1995 или 1996). Тут дело в том, что лекции были только 2 года, по 1 шт. в неделю, семинары были семестр, но зато были выделены часы доступа в выч. центр на всё время обучения на лабораторные, а на III курсе сдавали экзамен. Т.е. формально обучение занимало 3 года. Это всё, как я понимаю, связано с (а) необходимостью выделить определённое количество часов для записи в приложение к диплому, (б) для выплаты з/п преподам.

mister_VA ★★
()
Ответ на: комментарий от mister_VA

Фраза «им. Жданова» охватывает очень длинный период.

1996 год выпуска – не было там у чистых математиков три года программирования на паскале. Может быть ты слил вместе годовой(?) курс информатики в котором были всякие алгоритмы, системы счисления и пр. и который к паскалю не имел никакого отношения, кроме разве что каких-то примеров, с курсом вычмата (1 или 1.5 года), который был про устойчивость разностных схем, численное интегрирование и пр. и в котором была выч. практика полгода, которую как раз тогда на паскале и делали? Ничего из этого в принципе не является обучением языку программирования Паскаль.

Что в курсах было и в каком объеме лекции и практики в Выч.Центре?

У тебя же есть вкладыш к диплому – посмотри, мне действительно интересно, т.к. через 4 года после твоего выпуска там не было никаких намеков на то, что ты говоришь. Вообще никаких.

soomrack ★★★★★
()
Ответ на: комментарий от soomrack

про 500 на программирование

Если мы про потоковые лекции на первых курсах, то так оно и было, даже на нашем маленьком мат-мехе училось 300 человек.

есть только одна аудитория (01)

У баобаба? Вот в ней лекции и были, только она действительно почти пустой была. Но виртуально в ней находилось 300 человек.

На практических занятиях по программированию обычно группы делят…

… по количеству доступных компов, что диктуется… нормами СанПин.

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

Вот если честно, то я вообще не вижу смысла в лекциях, но переход к чисто семинарской методологии никто не продвигает. Да, когда нас из всей группы осталось 12 человек, то спецкурсы проходили лишь в виде семинаров.

Но то про математику, а вот конкретно программирование увы, выделенные нам преподы не блистали. Я вот вообще считаю Паскаль бесполезным для математиков, хотя на нём в лабораториях физики твёрдого тела или механики даже прикладные проги писали. Потому что впихнуть на те компы Борланд Си было невозможно. Там же, куда Си влезал, использовали Си.

mister_VA ★★
()
Ответ на: комментарий от soomrack

с курсом вычмата (1 или 1.5 года)

Курс вычмата был на программируемых калькуляторах. Допускался любой ЯП, доступный студенту на «левом» компе. Я часть работ вообще делал вручную на инженерном калькуляторе, поскольку это было быстрее, чем запрограммировать те ПМК.

т.к. через 4 года после твоего выпуска там не было никаких намеков на то, что ты говоришь. Вообще никаких.

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

Я ж написал, что 3 года – это было формальность, поскольку раньше III курса итоговый экзамен не сдать. Т.е. пара лет – лекции, семинары, а потом только лабы. У вас, кстати, было доказательное программирование?

mister_VA ★★
()
Ответ на: комментарий от mister_VA

Если мы про потоковые лекции на первых курсах, то так оно и было, даже на нашем маленьком мат-мехе училось 300 человек.

На матмех тогда набор был около 500 человек в год: три отделения математиков плюс механики плюс астрономы…

Потоковые лекции в 01 были, но это была история, философия и прочая хрень, ни одна потоковая лекция по математическим дисциплинам не была больше чем на 4ре группы, т.е. не превышала 150 человек, вот ни одна на моей памяти.

soomrack ★★★★★
()