Как преподавать Си?
Когда пару лет назад передо мной стала задача научить первокурсников МФТИ программировать на Си, я столкнулся со следующей трудностью: как подобрать такую последовательность подачи материала, чтобы каждая новая тема опиралась на предыдущие темы, и при этом не требовала использования ещё не изученного материала?
Язык Си как будто специально создан так, чтобы иметь зависимость своих концепций друг от друга. Хотите написать программу, выводящую «Hello, world»? Будьте добры, включите заголовочный файл stdio.h (используется препроцессор), создайте функцию main (для этого нужно знать функции), создайте строковый литерал "Hello, world" (указатель на строку символов, оканчивающуюся нулём), вызовите функцию printf, и так далее (рисунок 1).

Рисунок 1. Написание простейшей программы сложения двух чисел требует глубоких знаний языка программирования
Решение проблемы, практикуемое многими преподавателями: «Чтобы сделать это, нужно написать вот так. Пока не пытайтесь понять, я расскажу вам это в конце курса». То есть некоторые вещи даются без объяснения, просто так. Я считаю этот подход опасным. Практика показывает, что если обучаемый многократно применяет приём, которого не понимает, то у него складывается собственное понимание этого приёма (зачастую ошибочное). Это приводит к тому, что студента потом очень сложно переучить и направить в правильное русло. Бывает и так, что студенты настолько уверенно применяют некоторые приёмы, что преподаватель забывает, что не рассказывал им об этом.
Я встречал нескольких студентов, которые в результате такого обучения считали, что char* — это строка. Не указатель, а просто строка, аналог паскалевского string. Звёздочка, по их мнению, означала «многократное повторение char». Эти студенты присваивали «строки» обычным присваиванием, читали их при помощи scanf, не выделив память, и так далее.
На мой взгляд, следующие концепции представляют опасность для студентов (в том смысле, что про них лучше вообще не знать, чем знать неправильно):
- массивы;
- строковые литералы, строки и строковые функции;
- указатели;
- функции ввода-вывода, так как они используют строки и указатели;
Нужно было построить курс так, чтобы исключить перечисленные вещи из начального изложения. Немного поразмыслив, я нашёл решение проблемы ввода-вывода, а также использования строк и указателей: отладчик. Он позволяет вообще обойтись без использования функций ввода-вывода. Значения всех переменных как на ладони; их не нужно никуда выводить.
Кроме того, нельзя было вырывать студентов из привычной среды обитания. Поэтому в качестве операционной системы была выбрана Windows, а в качестве среды программирония — Visual Studio. Красивый интерфейс Visual Studio изначально располагает студентов к себе. Они могут по шагам выполнять свою программу, возвращаться назад, смотреть и менять значения переменных, и даже менять исходный код программы без её перезапуска. Половину всего времени обучения студенты работали со своими программами в отладчике. В результате они с лёгкостью могли находить ошибки в программах. Это, я считаю, самое главное.
- базовые типы данных;
- переменные;
- функции;
- условный оператор if и оператор цикла while;
Этих знаний хватило для решения большого числа задач. Студенты легко справлялись с рекурсией, условиями и циклами. Никаких указателей и непонятных заголовочных файлов. Только функции, созданные своими руками. Переменные — коробочки с данными, функции — механизмы для перемалывания этих коробочек. Студенты сокращали дроби, вычисляли факториал и числа Фибоначчи, раскладывали числа на множители...
Пришло время узнать про память и указатели. Я рассказал о большой линейной виртуальной памяти, о коде программы, о глобальных переменных, о куче и стеке, о механизме вызова функций и передачи параметров. И об указателях. Когда студенты в совершенстве освоили арифметику указателей (включая оператор индексации), я дал им сведения о структурах (struct), функциях malloc и free. Стало возможным создавать массивы и более сложные структуры данных: списки, матрицы, и даже балансирующиеся деревья. Сортировка, поиск... набор решаемых задач расширился. Ну и ввод-вывод, конечно же; теперь его можно было смело давать студентам без риска возникновения неверного понимания.
Рассказывать про «строки» после этого даже не пришлось. Надпись char* была понятна студентам без всяких объяснений, ведь это было подмножеством ранее пройденного материала.
Массивы студентам я так и не рассказал. Это очень сложная, непонятная вещь, особенно в многомерном случае (многомерные массивы студенты легко делали своими руками). И, главное, массивы абсолютно бесполезны. Так ли часто вы используете их в своих проектах?
P.S. А потом начался второй семестр. Ассемблер, процессор, сопроцессор, регистры,... Студенты писали код перемножения чисел с плавающей запятой (включая денормализованные числа) при помощи битовых операций, и сравнивали результат «ручного» перемножения с результатом сопроцессора. Но это уже другая история...
Автор: Сухинов Антон
WWW: http://iproc.ru
Адрес статьи на блоге автора: http://iproc.ru/2011/01/teach-c/#post-4296
Date: 25.10.2011
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
- 1522 просмотра



Комментарии
8 комментария(ев)Дата: Втр, 25/10/2011 - 14:45
у меня педагогическая практика в этом году была уже, вёл две лекции и две практики у второго курса по Основам программирования, на Си++ они там то же. Тяжело на самом деле им объяснять это всё. Сам то ты понимаешь это уже на уровне каком то своём, а им донести весьма сложно, тем более что никто ничего не хочет учить
Дата: Втр, 25/10/2011 - 15:24
Многие-ли, к примеру, любят химию? Часть просто не воспринимают. Но вот на днях видел ролик на ютубе про одного МГУ-ушного препода, проводившего лекцию-демонстрацию, так любо -дорого глядеть было.
Дата: Втр, 25/10/2011 - 16:03
там они ещё в консоли все проги пишут. Я помню, когда начинал с консоли в универе, тоже ничего не понимал и не хотел учить, т.к непонятно нифика зачем нужно это. Только когда на визуальные приложения перешли, более-менее интерес проснулся у меня.
Дата: ПТ, 28/10/2011 - 05:58
я когда начал писать приложения с окнами понял почему все в консоли пишут. Потому что так быстрее создаешь проект и не заморачиваешься на интерфейсе. ИМХО с консоли и надо начинать учить
Дата: ПТ, 28/10/2011 - 17:38
Согласен, надо сначала логику запомнить и операторы, обычно делаю так:
Pascal -> Delphi
QBasic -> VisualStudio
Дата: Втр, 25/10/2011 - 15:42
raxp, ссылку дашь на ролик?
Дата: Втр, 25/10/2011 - 16:52
Конечно, "наглядно о жидком азоте":
]]>
]]>
Дата: СР, 26/10/2011 - 23:47
У меня этот преподаватель ведет один предмет. (НГУ ФФ)
И само видео в НГУ. Это Аудитория Будкера (БА/БФА)