Страуструп: наставления начинающему программисту 5

Posted by Андрей on Июнь 26, 2008

Прочитал интервью Бьерна Страуструпа для австралийского ComputerWorld. В этом интервью ему задают вопрос:

Do you have any advice for up-and-coming programmers?

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

Можете что-то посоветовать начинающим программистам?

Изучайте основы программирования: алгоритмы, архитектуру машин, структуры данных и т.д. Не копируйте слепо подходы из одного приложения в другое. Вы всегда должны знать, что вы делаете, быть уверенными, что ваша программа работает, и твёрдо знать, почему она работает. Не думайте, что вы можете предсказать, какой будет индустрия программирования через 5 лет и чем именно придётся заниматься вам, поэтому учитесь более общим и полезным приёмам и подходам. Старайтесь писать код, который лучше, код, который больше соответствует вашим принципам программирования. Работайте так, чтобы программирование в большей степени было профессиональной деятельностью, а не низкоуровневым «хакерством» (программирование — это и ремесло, но не только ремесло). Учитесь на классике в области разработки и с помощью лучших книг, не надо полагаться на «how to» и документацию в онлайне — она недостаточно глубоко затрагивает вопросы программирования.

Зачем нам нужны высокоуровневые языки прогаммирования? 3

Posted by Андрей on Апрель 25, 2008

Наткнулся на чудесный пост от Moshe Zadka. Почему мы пишем программы сегодня на Python, Ruby, PHP, а не на старом добром Си? Почему используем заведомо менее эффективные (как по памяти, так и по скорости языки программирования).

Если кратко, Moshe приводит следующие доводы:

  • не все могут писать на Си, многим это просто недоступно, но это даже хорошо, если становится больше программистов — больше программ, больше удововлетворения для общества;
  • на языке высокого уровня писать быстрее — быстрее выпустим продукт на рынок, следовательно опередим конкурентов;
  • слишком много ошибок в программах на Си, которые можно избежать в языках высокого уровня;
  • люди готовы поменять деньги, вложенные в более мощное железо, на более «умные» программы.

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

Как преподавать C++? 8

Posted by Андрей on Март 30, 2008

Кого мы хотим подготовить, обучая студентов программированию на C++? Что они должны вынести из курса? Мне кажется, важно научить писать программы. Красивые, эффективные, сопровождаемые. Язык — лишь инструмент программирования. И надо научиться пользоваться инструментом. Вот когда в автошколе учат вождению машину, совсем не обязательно знать тонкости устройства шины CAN, обеспечивающей связь всех устройств автомобиля. Да, надо узнать, что такое тормоза, руль, двигатель, но на каких-то деталях надо остановиться, и, самое, главное, надо научиться пользоваться автомобилем (то есть водить автомобиль) безопасно, уверенно и т.п.

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

Вот объясните мне, кто-нибудь использовал перегрузку наряду с виртуальностью?

class A
{
public:
    virtual int f();
};
class B : public A
{
public:
    virtual int f(double);
};

Что это нормально, это работает? Зачем нужны эти знания? А кто перегружал функции, расположенные в разных областях видимости?

class A
{
    void f(char);
public:
    void f(int);
};

A a;
a.f('a');

Ну кто такое делает в реальных задачах? Зачем студентов заставлять разбирать эти примеры?

Как я понял из интервью Бьерна Страуструпа, это проблема преподавания Computer Science не только на факультете ВМиК МГУ. Он говорит, кого мы готовим? lanugage lawyers? По-моему, это очень точно английское словосочетание… Мы готовим студентов стать членами комитета ISO по стандартизации C++?

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

Кому это нужно? Самоудовлетворение от задалбливания в умы студентов бесполезных знаний?

Почему мы не экзаменуем их на умение программировать? Ну или хотя бы на знание базовых конструкций языка? Зачем такие извращенные примеры? Если бы я опубликовал весь вариант работы, которую писали студенты, думаю, многие были бы в шоке. Я уверяю, что подавляющее большинство потрясающих, талантливых C++-программистов не смогут решить этот вариант на «пять». Но от этого они не становятся хуже, а претензии надо предъявлять тем, кто составил такую программу курса, предъявляет такие требования к студентам. Как они могут полюбить такой предмет?

По-моему, пора остановиться и сменить ориентиры.

C++, просто смешно… 3

Posted by Андрей on Февраль 07, 2008

Что выведет данный код?

#include <stdio.h>

struct A
{
    A(int x = 3) { printf("%d\n", x); }
};

struct B: virtual public A
{
   B() : A(4) {}
}; 


struct C: virtual public A
{
  C() : A(5) { }
}; 

struct D: public B, public C
{

};

int main()
{
    D d;
    B b;
    C c;

    return 0;
}

Ответ:

3
4
5

Что самое смешное, можно из D::D() явно вызвать конструктор A с другим параметром. Наслаждаемся в C++ смесью виртуального наследования, раздельной компиляции и полученной кривости.