Обсуждение решения учебной задачи на C++ (с лямбдами и auto-переменными)
Отщеплен от топика Помогите с двумерным массивом, пж!
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.
М-да... От традиционных «плюсов» здесь остались
int
,main
,if
,return
, вывод на консоль и фигурные скобки. Выглядит красиво, но это уже другой язык ((Это как раз этот язык.
А то, что описываете Вы — это Си с классами.
К сожалению, в наших ВУЗ'ах зачастую,
преподаватели кроме этого больше ничего не знают.
Вы так говорите, как будто это что-то плохое :-)
По теме: ваше решение врядли подойдет ТС, ибо подразумевается алгоритмическое решение задачи (нахождение минимума и максимума).
Вы используете
std::minmax_element
. Это может быть правильным подходом при решении практических задач, но здесь оно примерно из той же оперы, что использоватьstd::qsort
в студенческой задаче на реализацию быстрой сортировки.Если нужно писать на C, то надо писать на C.
А на C++, желательно, писать на C++.
Во-первых, это может нам поведать только ТС,
а во-вторых, кто-то найдет пост и посмотрит,
что есть готовые решения.
В C++ имеется std::sort, который, к слову,
не обязан быть реализован с помощью быстрой сортировки.
И "реализация быстрой сортировки
для сортировки массива чисел" !=
«Сортировать массив чисел».
Первая задача требует реализацию самой сортировки,
вторая — конечный результат.
Не вижу в вопросе ТС слов
"реализовать алгоритм поиска
максимального и минимального чисел...",
однако вижу задание
"Найти в каждой строчке матрицы
максимальный и минимальный элемент",
в котором не указаны ни средства,
ни способы решения.
Я предоставил свой вариант.
Не нравится — проходите мимо.
Не можете оставаться равнодушным
к проблеме ТС — пишите свой вариант.
А если нужно писать на C с классами?
Тогда берете компилятор восемьдесят лохматого года,
берете документ «C with classes»,
и пишите код в соответствии с этим документом.
Ну и для ознакомления: http://www.lb-stuff.com/cc
И еще: https://www.google.ru/url?sa=t&source=web&rct=j&url=http://www.stroustrup.com/hopl2.pdf&ved=0ahUKEwibw5LQp77RAhWmJZoKHXupC_IQFggaMAA&usg=AFQjCNFjCVhRehjUi24ycZ7sqACDCfEXLw&sig2=f16iRFp_osmtyJUEGHxkkA
Речь о том, что нет ничего плохого в использовании ограниченного подмножества языка, если это оправдано задачей.
А в использовании готовых отлаженных инструментов что плохого?
Тем более, это получается намного быстрее и проще.
Я не встречал такого, чтобы реальная задача требовала своего велосипеда,
за исключением случаев, когда задача заключается именно в изобретении велосипеда.
Но и в этом случае, по возможности, используется максимум готовых средств.
А что касается студенческих задач, то меня удивляют задачи,
в которых можно использовать std::istream, из стандартной библиотеки,
но нельзя использовать std::string из этой же библиотеки.
Тоже самое касается и C — scanf можно, strtok — нельзя.
Что это за бред? И не говорите, что мол «вывод не важен», важен алгоритм.
Вывод тоже крайне важен. Давайте-ка, запилите годный, настраиваемый вывод double,
используя только функции ОС. Ах, да, ОС — это тоже алгоритмы,
надо бы и ОС свою запилить сразу, а то че готовое-то использовать,
задача же не позволяет использовать готовое. )))
И да, в задаче ТС нет указаний по используемым средствам.
Не надо сваливать всё в одну кучу.
Во-первых, есть учебные задачи. Их цель научить человека определённому стилю мышления, необходимому для работы программистом (и т.п.). Это с одной стороны. С другой стороны, человек, применяющий библиотечную функцию, например, сортировки, должен понимать как это работает.
Во-вторых, «матчасть надо знать». Т.е. иметь понятие о том, что реализовано [хотя бы] в стандартной (не говоря уже про сторонние!) библиотеке, что бы, в случае чего, мучительно не изобретать велосипед, а воспользоваться готовым решением. Что, собственно, и продемонстрировал Croessmah своим решением.
В-третьих, в наших учебных заведениях программирование, к сожалению, часто преподают, мягко говоря, люди некомпетентные в данной области. Как следствие, имеем массу некорректно сформулированных заданий. А если это ещё помножить на раздолбайство, чего греха таить, самих учащихся (не дописал, перепутал, неправильно списал и т.д.), то и получаем в итоге «рекуррентное соотношение 1 = 1». Поэтому что либо сказать о соответствии представленного решения нуждам и чаяниям ТС, может сказать только ТС, который, по ходу, уже давно забил не только на этот топик, но и на этот ресурс в целом. Так что данное обсуждение — это так... — потрепаться на любимые темы под рюмочку чая ))
В-четвёртых, C++ — велик и могуч, почти так же, как русский )) И писать на нём можно в разных стилях, и используя различные подмножества языка. Если выбранный стиль (и подмножество языка) оптимально удовлетворяет решению конкретной задачи, то не вижу причин, применять другие языковые средства.
Но у «величия и могущества» есть и другая сторона. Есть подмножество языка, которое (на данном историческом этапе) реализовано во всех компиляторах, включая такую экзотику, как компиляторы для встроенных систем (т.е. это даже не от действующего стандарта зависит). Есть подмножество языка, которое реализовано почти во всех компиляторах. Как правило, это возможности предыдущего (а то и пред-предыдущего) стандарта. Для текущего стандарта уже начинаются всякие весёлые вещи: где-то что-то не реализовано вообще, или реализовано не в полном соответствии со стандартом, или реализовано своеобразно. С «будущими» стандартами, понятное дело, всё ещё веселее. Т.е. нет никакой гарантии, что программа на C++, написанная в строгом соответствии с действующим (!) стандартом, успешно скомпилируется на другом компиляторе для той же платформы (я уже не говорю про кроссплатформенную переносимость на уровне исходного кода). Что есть печально...
Поэтому оптимально соблюдать некий баланс между возможностями языка, особенностями конкретной задачи, личными пристрастиями и погодой на южном полюсе Венеры. IMHO, конечно.
Это — учебные задачи. Если изучается тема «массивы и указатели», и студентам необходимо освоить навыки работы именно с массивами и указателями, то логично, что запрещают использовать
std::string
(а возможно, что и<cstring>
), потому что при этом не достигается цель, которая состоит в изучении массивов и указателей, а не в изучении возможностей классаstd::string
или набора функций из<cstring>
.Это какое? Для справки, многое из привычного может неверно работать.
Это отражено в документации.
Или сначала пользуем, а потом читаем инструкцию? )))
Я не знаю ни одного компилятора,
который бы на 100% поддерживал действующий стандарт.
Даже C++03 реализовать целиком не удалось.
Да? Исключения базовые же вещи?
Посмотрим, где там в embedded рады и поддерживают,
их даже не в embedded не все используют.
Именно поэтому нужно использовать голые указатели,
балансировать на грани UB,
писать багнутые велосипеды и т.д.
Ведь язык и так сложный, а мы хотим
сделать его еще сложнее. Только хардкор.
Что я и продемонстрировал кодом,
однако пришли умники с криками, —
"НИ ТАК, БИДАЛАГА, СМАРИ КАК НАДА.
УКАЗАТЫЛИ ДАЛЖНЫ БЫТЬ, ИНАЧЕ НИ ТАК".
Мой вариант решает поставленную задачу,
однако, кое-кто сказал, что надо использовать
другие языковые средства. Логика не лопнула? )))
Да, есть. И язык и фреймворк навязывает стиль.
Писать на C++ в стиле C — это даже звучит не очень.
Как там у Макконнелла, — "писать можно
на языке и с использованием языка", так, вроде?
Я раньше считал, что подход снизу вверх единственно верный.
Теперь, с опытом, я в этом сильно сомневаюсь.
Тогда и задачи нужно ставить соответственно.
Еще раз — где ТС упоминает суть задачи или средства?
Нигде? Получите и распишитесь тогда!
Ну вот смотрите, я понятия не имею
как работает внутри видеокарта,
однако могу использовать готовые решения.
Также многие пользователи Qt понятия не имеют
как оно реализовано на уровне того же WinAPI,
но это не мешает им использовать фреймворк.
При этом они работают более продуктивно.
В этом и заключается суть подхода сверху-вниз.
Пока одни изучают C-строки и гоняются за '\0',
другие уже пишут более серьезные приложения,
используя готовые признанные решения,
при этом спускаются к C-строкам,
но лишь при необходимости.
Таким образом — они изучают алгоритмы,
не отвлекаясь от самого алгоритма на детали,
которые не нужны для изучения алгоритма.
Это примерно тоже самое, что учиться
писать на консольных приложениях —
не отвлекаешься от алгоритмов на GUI.
Так что готовые решения очень
сильно помогают в развитии мышления.
НО! Конечно же, знать что к чему тоже никогда не повредит.
Но нужно знать меру, а не кидаться на людей со всякими
это тот же самый язык, более того,
это даже рекомендуется многими специалистами,
в т.ч. самим создателем языка, наверное,
ему всё же виднее, какой стиль задумывался в языке.
Если кому-то что-то не нравится — мимо.
Если не понятно что-то — объясню как смогу.
Я могу написать и в том и в том стиле.
Если надо, можно и под микросхему написать,
опыт в схемотехнике и программировании
embedded у меня имеется, даже сейчас у меня
в мыслях (и не только) проект,
но запчасти еще в пути, жду.
Я выбрал способ решения задачи тот,
которым посчитал нужным и правильным,
хотя там есть огрехи.
Я не пью чай рюмками.
Надеюсь, я донес до Вас свою точку зрения.
А этот простой треп пора закончить.
Лучше потрепаться о чем-то другом.
Излишне эмоционально. Поэтому аргументация хромает.
Croessmah, что ж ты такой радикал (только ситхи все возводят в абсолют :-)
По теме: конкретно в этой ситуации использование винегрета из STL для решения такой задачи с вероятностью 90% вызвала бы недоумение у преподавателя.
Из прагматичных соображений, я об этом написал.
Срачик предлагаю продолжить (топик можно отбранчевать в новый).
Ваша как раз хромает.
Мой способ проще как для понимания,
так и для разработки, у Вашего кроме как,
«студентам же учиться надо»,
более ни одного аргумента нет, увы.
А так, да, бесите вы меня со своими абсолютно
беспочвенными и бесполезными как для меня,
так и для вас скучными наскоками. )))
Пусть хоть огнем плюется, моё какое дело?
Я это делал не для преподавателя.
Это я радикал? Вы тему перечитайте,
это ж вы набросились с вашим «НИ ТАК НАДА»,
вместо того, чтобы предложить другое решение.
Так что это вы неприемлите такого решения,
а не я вашего, кстати, отсутствующего. )))
Глупая идея, честно.
Хотите — сритесь ходь до опупения,
а я пошел, мне более это не интересно.
Вас хоть лбом об стену, всё равно бестолку,
так и будете «НИ ТАК НАДА, ПРЕПАД ДИБИЛ»,
вместо «ВОТ ЕЩЕ ОДИН ВАРИАНТ».
P.S.
И да, скоро варианты с C++17 начну выкладывать,
можете хоть кипятком писать, мне всё равно, ребят,
но я это делаю не для вас и не для ТС даже. :)
Не уподобляйся ;-)
Никто на тебя не «наскакивает» и не пытается учить, как надо писать программы на С++ правильно.
Вот уж не сказал бы... Для понимания работы с массивом (без указателей) нужно понимание трёх простых вещей: ячейка памяти, последовательное расположение этих ячеек и цикл
for
(в примитивном виде). Для понимания твоего кода нужно хотя бы поверхностно понимать что такое объекты, шаблоны, итераторы, лямбда-функции, автоматический вывод типов, плюс знать какие функции есть в STL и какие подойдут в данном конкретном случае. Да и стиль программы заметно сдвигается в сторону функционального программирования.Если на всё это смотреть с точки зрения преподавания С++, то вопрос в том, что ставится целью обучения. (Понятно, что умение писать программы на С++.) Я считаю, что изучение низкого уровня (а) необходимо и (б) нужно изучать на начальном этапе. Поскольку понимание того, как работают высокоуровневые вещи, базируется на этих знаниях. А обучение только высокоуровневым вещам — штука опасная, как в плане тонких ошибок, возникающих вследствие непонимания принципов работы, так и в плане эффективности/объёма программ. В конце концов, это C++, а не скриптовый язык типа Ruby или JavaScript. Немного разные «экологические ниши». (Хотя и при использовании скриптовых языков надо всё-таки понимать что происходит «под капотом».)
Конечно, при обучении можно сдвинуть акцент в сторону более крупных смысловых блоков и функционального программирования. Но для такого подхода есть более подходящие языки, типа Haskell. С++ хоть и мультипарадигменный, но в изначально всё-таки императивный и объектно-ориентированный. Остальные плюшки навешивались потом.
Этот момент спорный. Я, конечно, не могу знать какие соображения по данному вопросу имеются в голове г-на Страуструпа, но судя по некоторым высказываниям, Страуструп не в восторге от изменений, вносимых в последние стандарты. (Точных ссылок на публикации дать не могу: не помню где это было.) Это раз. В книге Страуструпа «Язык программирования C++», начиная с первой редакции (1989) и заканчивая «special edition» (2000), последней переведённой на русский, нет никаких акцентов на преимущественном использовании возможностей STL. Это два. И последнее, вероятно, что взгляды Страуструпа на C++ со временем (более 30 лет однако!) тоже менялись. Возможно, что в четвёртой редакции (2013) книги другие акценты. (Хотя я что-то сомневаюсь.)
Учитывая контингент вопрошающих на этом ресурсе, думаю, что результатом представления преподавателю такого решения будет однозначный разворот на пересдачу. Мотивировка: либо просто «вы не знаете как работать с двумерными массивами», либо, после пары вопросов по этому коду, позорное «это не вы писали программу» (и будет прав).
«Другое решение» я изложил в двух статьях на этом ресурсе, посвящённых работе с массивами.
Помнить полное описание для каждого (даже одного!) компилятора — не реально. Поэтому сначала пользуем, в предположении, что компилятор удовлетворяет стандарту. А потом лезем в документацию, что бы выяснить что за странная ошибка появляется на ровном месте.
Язык — да, а фреймворк — штука опциональная.
А почему нет? (Пофиг как звучит, а по сути?)
При этом я отнюдь не призываю к всеобщему даунгрейду. Где-то удобнее писать на современном С++, где-то — на «С с классами», где-то — на «почти» С.
Сразу: параллель с видеокартой некорректна. Мы же не разрабатываем другую железку, с которой эта видеокарта должна взаимодействовать.
Qt — это фреймворк над фреймворком (WinAPI). И его использование будет безоблачным ровно до того момента, когда потребуется задействовать то, что есть в WinAPI, но не реализовано в Qt. Если есть понимание, как работает WinAPI, то проблема решится безболезненно.
Человек, обладающий меньшей суммой знаний, работает более продуктивно? Ну-ну...
Принципы программирования «снизу вверх» и «сверху вниз» — это немножко не из этой оперы.
Угу... А потом мы удивляемся как дистрибутив офисного пакета занимает несколько гигабайт, а для его развёртывания требуются десятки гигабайт на харде, а для работы — необходимо дохрена памяти и неслабый процессор.
Да, пишут... при этом не смущаясь забивают гвозди микроскопом и колют орехи большой государственной печатью.
А вот это — уже совершенно отдельный вопрос.
Вот же:
С этого и началось.
Где у ТС упоминаются массивы? Там сказано — матрица.
Как она реализована — не сказано.
Скажите это авторам одной из книг для начинающих,
где обучение как раз начинается STL.
Если найду книженцию, напишу название.
Нужно уметь писать программы,
а не только писать на C++.
Многие с этим не согласны и успешно практикуют подход сверху-вниз.
А где я писал «ТОЛЬКО»?
Я писал «СНАЧАЛА».
Это разные вещи.
Собственно упертость в этом вопросе тормозит развитие C++,
фич, необходимых разработчикам и ненужных некоторым из коммитета.
У него не одна книга, например. :)
It is common for programmers to underestimate these problems. However, many experienced programmers have been defeated by the innumerable variations and combinations of these simple array and pointer problems.
The solution is not to litter your code with pointers, arrays, news, and deletes. If you do, “being careful” simply isn’t enough in realistically sized programs. Instead, rely on vectors, RAII (“Resource Acquisition Is Initialization”; see §19.5), and other
systematic approaches to the management of memory and other resources.
Это первое, что попалось. :)
Повторю еще раз — я пишу не для преподавателя.
Кстати, мой знакомый учится в ВУЗ'е,
и там подобные решения приветствовались,
причем на первом курсе, так что не надо за всех твердить. :)
Вам написать свое мнение?
Часто работаете на разных компиляторах?
Тогда в любом случае придется часто лазить в документацию.
Не видел ни одного 100% соответствующего.
Для писанины в стиле C — есть C.
Или нужны классы? Тогда это уже ООП,
и идти туда с голыми массивами не особо приятно,
за исключением изготовления «кирпичиков».
Конечно нет, но раз мы выводим на экран букаффки,
то, с точки зрения подхода снизу-вверх,
мы должны уметь напрямую с видюхой работать.
Для 90% случаев этого не нужно,
либо есть готовые решения.
Причем здесь сумма знаний?
Я про выбранный подход.
Пока один считает байты из которых состоит строка,
второй оперирует строками, как целыми сущностями,
причем если изменится сущность (например, другая кодировка будет),
то байтописцу придется намного больше переделать.
Однако это работает! Именно работает!
И работало оно уже в то время,
когда другие еще в стадии зачатия были.
И да, не нужно ставить в один ряд тех,
кто тупо говнокодит и тех,
кто пишет максимально универсально.
Я Вас не чпо... кхм, ну Вы поняли про брудершафт.
Грубо? Зато справедливо.
И еще раз, чтобы Вы усвоили, наконец-то.
Писал я это НЕ ДЛЯ ВАС И НЕ ДЛЯ ПРЕПОДА,
и не надо меня учить как делать,
разберусь без Ваших компетентных мнений.
Можете общаться дальше между собой.
Большая просьба меня не упоминать.
Вы там перепутали много чего и с чем.
Так что этот аргумент получился против Вас.
И по книге Страуструпа (да там целый раздел о этом):
А еще у него с первой главы идет применение векторов, строк и т.д.,
т.е. никакие «мы не учили шаблоны» не мешают совершенно.
Даже классы рассматриваются после.
И еще вот:
Из переведенного издания:
Брюс Эккель — Философия C++
А вот еще книжка.
Стенли Липпман, Жози Лажойе, Барбара Э. Му — «Язык программирования C++. Базовый курс»
Думаю, содержание говорит само за себя:
И вот из введения:
В этом издании не нашел,
но в старом издании было подробно расписано,
почему они выбрали именно такой подход.
Кратко — этот подход они испытывали на студентах,
и он оказался намного эффективнее.
Не думаю, что Вы или я можем с ними поспорить на равных. :)
Ой, вру! Немного в другой книге они это описывали.
Эндрю Кёниг, Барбара My — Эффективное программирование на C++.
И, в соответствии с этим, могу порекомендовать всё-таки,
посмотреть на язык «C++ с совершенно иной точки зрения, с которой вам еще не приходилось на него смотреть».
А с Вашей точки зрения я на него уже насмотрелся, простите уж.