Всем доброго времени суток!
Это статья о том, почему же все-таки стоит выбрать C++ в качестве первого языка программирования для обучения студентов, и немного о проблемах преподавания в ВУЗах. Часть суждения, касающегося процесса обучения, основывается на личном опыте преподавания (три года, во время учёбы в аспирантуре), а также на общении с преподавателями и студентами.
Рассматриваются преимущества языка программирования C++ именно для обучения и с точки зрения лучшего понимания основных концепций. Остальные кандидаты на роль первого языка (Pascal/Python/C#/Java) не рассматриваются, дабы не разжигать холивар. Еще раз отмечу: не для промышленной разработки и не с точки зрения такого субъективного критерия, как удобство.
Написано под впечатлением откровенно рекламного поста «Delphi XE5 как основа для обучения программированию» (на момент написания, доступна только версия «от гугла»).
0 Введение
Для начала, хотелось бы отметить, что для студентов не профильных специальностей вопрос выбора первого языка программирования не рассматривается. Основы алгоритмизации (если они необходимы) можно осваивать хоть на Python, хоть на C++ (Java, C#, Pascal и т.д.). В данном случае, чем проще язык, тем он лучше: у людей необходимо сформировать хоть какую-то культуру алгоритмического
Несмотря на всю очевидность написанного выше, многим студентам-экономистам первого курса преподают программирование на Pascal на практических занятиях по информатике. Студентам, которые ещё толком не умеют работать с MS Word. Польза от таких занятий весьма и весьма сомнительна. Точно так же, студентов-математиков могут пару лет учить программировать на C++/C#/Java… но зачем? Гораздо полезнее для последующего применения своих знаний изучить программы вроде Mathcad, Simulink, Surfer и т.д.
Учитывая вышеизложенное, рассмотрим процесс выбора первого языка исключительно для студентов профильных специальностей (например, «Программная инженерия») и смешанных специальностей с уклоном в сторону IT (например, «Прикладная математика и информатика»). Во-первых, учебный план таких специальностей предполагает достаточное количество лекций и практик (т.к. рассматривается первый язык, учитывается только первый курс): для двух связанных дисциплин (информатика и программирование) около 230 часов, в зависимости от специальности. Во-вторых, наличие заинтересованности и определённого склада ума у студентов. Такие студенты чаще всего уже пробовали программировать, а возможно даже и написали сайт/игрушку. Две эти причины, в совокупности, дают неплохую базу для начала обучения и понижают порог вхождения для обучения языку. К тому же, выпускникам рассматриваемых специальностей предстоит в дальнейшем работать в индустрии разработки ПО. Следовательно, выбор первого языка для них особо важен.
1 Почему же C++?
На первом курсе закладывается базис для дальнейшего обучения и формируется подход студента к дальнейшему получению знаний. Язык программирования играет здесь не последнюю роль.
Для того чтобы выбрать C++ в качестве первого языка программирования существует четыре причины:
- Компилируемый язык со статической типизацией.
- Сочетание высокоуровневых и низкоуровневых средств.
- Реализация ООП.
- STL.
Рассмотрим данные причины более подробно.
Компилятор. Тут C++ предстаёт во всей красе. Множество компиляторов, консольные команды, этапы сборки программы… Да, первую программу нужно написать в простом текстовом редакторе без подсветки синтаксиса и автокомплита, найти чем и как её можно запустить. Такой подход формирует у человека некоторое понимание того, как всё устроено:
- Код программы – это просто текст, который сам по себе не заработает.
- Компилятор – это отдельная программа, которой надо указать, что и как сделать с исходным кодом, чтобы он превратился в исполняемый файл. Текстовый редактор – это тоже отдельная программа, предназначенная для написания исходного кода.
- Существуют опции сборки, и существует не один компилятор.
- Исходный код, написанный программистом, может быть предварительно обработан и изменён (например, препроцессором).
Будущий специалист осознает, что код сам по себе не запускается (в дальнейшем он быть может и заинтересуется, как работает, например, интерпретатор Python или JIT-компиляция). Человек будет задавать себе вопросы: «А почему?», «А в чём отличие?», «Как?». Не будет иллюзий по поводу того, что всё работает по нажатию двух волшебных кнопок или в интерактивной командной строке. Студент будет знать, что процесс сборки программы можно настроить и что исходный код может быть обработан сторонними программами. В будущем, при использовании IDE, человек будет понимать, что это всего лишь удобный комплекс программ, выполняющий большую часть рутинных операций и в случае недостаточной гибкости от неё можно отказаться или расширить.
Статическая типизация. На примере языка со статической типизацией проще понять, что такое тип данных, зачем он нужен и от чего зависит. Видно, что собой представляет объявление, определение и инициализация. Использование языка C++ даёт это явно увидеть, что способствует дальнейшему пониманию того, как работают эти механизмы в других языках. Помимо этого можно на реальных примерах понять, чем беззнаковые целые отличаются от целых со знаком, чем отличаются числа двойной и одинарной точности, чем отличается символ от строки и т.д.
Высокоуровневые и низкоуровневые средства. Использование таких средств, как указатели и динамическое выделение памяти, позволяет понять (или в дальнейшем способствует пониманию), что такое стэк, куча, стэк вызовов, раскрутка стэка и т.д. Помимо этого, на практике закрепляется понимание концепции адресов и адресной арифметики. На примерах демонстрируется, что память надо выделять, освобождать, потому что она не бесконечная, что существуют утечки памяти. В будущем, при изучении языков с GC проще будет понять, что же это такое.
Отдельно стоит отметить простой механизм передачи значений по ссылке, значению, указателю и перенос объекта. Что такое изменяемые и не изменяемые параметры. В дальнейшем данные концепции могут быть использованы и при изучении других языков. Студент будет понимать, например, что объект в языке N передаётся по ссылке, и если его значение изменить в функции-члене, то оно изменится везде.
Реализация ООП. Это относительно чистая реализация ООП без всякого синтаксического сахара (относительно некоторых других языков). Чётко разграниченные уровни доступа к членам класса, возможность множественного наследования и динамический полиморфизм дают возможность быстро усвоить основные концепции ООП (абстракция, наследование, инкапсуляция и полиморфизм). Указатели и динамическое выделение памяти позволяют наглядно понять такие важные механизмы, как upcasting и downcasting. В дальнейшем, основываясь на этих знаниях, легко можно понять весь синтаксический сахар в других языках. Необходимость контроля ресурсов (в том числе и «правило трёх» или уже «правило пяти», с учётом C++11), захват их в конструкторе и освобождение в деструкторе также способствуют более глубокому пониманию ООП.
Стоит отметить такой важный момент, как не принудительное ООП. То есть данный подход к программированию применяется тогда, когда это удобно, и его можно смешивать, например, с функциональным программированием. Это способствует формированию понимания того, что средства реализации выбираются исходя из задачи.
STL. Сама по себе концепция шаблонов C++, генерации кода и применения широкого спектра алгоритмов к различным контейнерам положительно влияет на процесс обучения. Здесь все на поверхности и понятно, почему можно создать вектор целых чисел и вектор пользовательских объектов на основе одного класса-контейнера. Почему можно применить некоторую операцию к последовательности объектов или как отсортировать объекты, для которых не предусмотрена встроенная операция сравнения. Можно понять, как осуществляется доступ к элементам, и узнать о категориях итераторов. Помимо этого закрепляется понимание обобщённого программирования.
2 Немного о проблемах обучения
Процесс обучения, пожалуй, одна из наиболее существенных преград, для того, чтобы реализовать все то, о чём написано в предыдущем пункте. Вероятно, этот вопрос не касается топовых IT-вузов, но если взять рядовые образовательные учреждения, то ощущается дефицит квалифицированных кадров и слабая мотивация студентов. Для большей части практических дисциплин редко привлекаются специалисты, занимающиеся непосредственно разработкой ПО. Например, человек, который не применял STL в реальных проектах, вряд ли сможет объяснить, как это делать, и главное зачем. Так же, как и преподаватель, искренне считающий, что программирование на Delphi с формочками уже есть самое настоящее ООП, учитывая, что весь код (без намёка на собственные классы, абстракцию и инкапсуляцию) пишется в обработчике нажатия на кнопку с очень понятным именем «Button1», не способствует процессу обучения. Проблемы есть и со стороны студентов, которые толком не поняли, куда и зачем они поступили. Многие студенты, не имеют мотивации к дальнейшему обучению и пониманию, а также и к самообразованию. Не смотря на то, что такие студенты и преподаватели прекрасно дополняют друг друга, в конце обучения не получится специалист, претендующий на junior-вакансию.
3 Заключение
В настоящий момент в мире разработки программного обеспечения сложилась ситуация, что в цене знание определённых технологий и опыт их применения, а не понимание. Современному обществу необходимо много программистов, которые могут выполнять строго определённые функции. Отчасти этому способствуют и развивающиеся технологии разработки. Возможно, что большая часть разработчиков, умеющих просто пользоваться определённым набором инструментов, никогда не столкнётся с «законом дырявых абстракций». Однако людям, претендующим на должности ведущих разработчиков, занимающихся оптимизацией и вопросами архитектуры, необходимо более глубокое понимание того, как всё устроено. Одним из факторов, приводящих к такому пониманию, может отказаться и верный выбор первого языка программирования. На основании этого, язык C++, являющийся статически типизированным, компилируемым, поддерживающий низкоуровневую работу с памятью и не перегруженную синтаксическим сахаром реализацию ООП, можно рекомендовать в качестве первого языка программирования.
Автор: vt4a2h