Кресты / Говнокод #5701 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
#include <iostream>

template <int n>
struct Solution
{
  static const int count = Solution<n / 10>::count + 1;
  static const int sum = Solution<n / 10>::sum + n % 10;
  static const int last = n % 10;
  static const int first = Solution<n / 10>::first;
};

#define DECLARE_ONE_DIGIT_SOLUTION(n) template <>\
                                      struct Solution<n>\
                                      {\
                                        static const int count = 1;\
                                        static const int sum = n;\
                                        static const int last = n;\
                                        static const int first = n;\
                                      };

DECLARE_ONE_DIGIT_SOLUTION(0)
DECLARE_ONE_DIGIT_SOLUTION(1)
DECLARE_ONE_DIGIT_SOLUTION(2)
DECLARE_ONE_DIGIT_SOLUTION(3)
DECLARE_ONE_DIGIT_SOLUTION(4)
DECLARE_ONE_DIGIT_SOLUTION(5)
DECLARE_ONE_DIGIT_SOLUTION(6)
DECLARE_ONE_DIGIT_SOLUTION(7)
DECLARE_ONE_DIGIT_SOLUTION(8)
DECLARE_ONE_DIGIT_SOLUTION(9)

int main()
{
  const int number = 1024; // <-- то самое число a

  std::cout << "Number of digits: " << Solution<number>::count << std::endl;
  std::cout << "Sum: " << Solution<number>::sum << std::endl;
  std::cout << "Last digit: " << Solution<number>::last << std::endl;
  std::cout << "First digit: " << Solution<number>::first << std::endl;

  return 0;
}

Это один из ответов к слезной просьбе какого-то школьника (студента) выполнить за него д/з на С++ в разделе development форума на ЛОРе. Такую программу нарочно хрен напишешь.

Само задание: «Дано натуральное число а (a≤100). Напишите программу, определяющую количество цифр в этом числе, сумму его цифр, выводящую на экран первую и последнюю цифру через два пробела».

Запостил: deniska deniska, (Updated )

Комментарии (119) RSS

    • ООП времени компиляции со всеми костылями вокруг этого (ШАБЛОНЫ) действительно съело мозг бедным приплюснутым.
      Ответить
    • Б. Тарас, наконец решился почитать про функциональную парадигму. Похвально.
      Ответить
  • а все таки человека, придумавшего преподавать школьникам плюсы -- надо четвертовать

    сначала надо человека сям научить и процедруному подходу
    потом грузить неокрепший мозг темплейтами
    Ответить
    • А в задании и не написано про темплэйты. Если школьник изъебывается с тем, что не знает и не давали, это вина препода?
      Кстати, и не школьник это писал -- это ответ на его просьбу. Так что школота в этот раз только свою лень показала.
      Ответить
  • Плюсанул сабж! Но вовсе не потому что говнокод, как раз наоборот - это достойно жить!
    Вычисления в компайл-тайме - уважаю!

    ЗЫ: любопытно, примут ли работу у того школьника?
    Ответить
            • Может он с философского фак-та, загрузит препода, мама не горюй 🙂
              Ответить
              • Проблема в том, что программирование на философском факультете преподаёт не философ, а человек с киберфака или мехмата. И на философию у него должен быть иммунитет.
                Ответить
                • Артефакт учебник математики: +5 резист к философии. 🙂
                  Ответить
  • этот код не всегда будет компайл таймом... чтоб был компайлтаймом надо заменить инты на enum'ы... вот так

    enum
    {
    count = Solution<n / 10>::count + 1,
    sum = Solution<n / 10>::sum + n % 10,
    last = n % 10,
    first = Solution<n / 10>::first,
    };

    компилятор может забить на разворачивание интов и тупо вставить код который их вычисляет...
    Ответить
    • Компилятор "Некрофил+"?)) Просто что-то я не застал компилятора, который считает константы.
      Ответить
    • Не может, вообще не может. Шаблоны разворачиваются 100% во время компиляции и никак иначе.
      Ответить
      • я сталкивался с ситауцией когда генерился код вычисления, мне это стоило нескольких часов отладки...
        Ответить
        • Значит было разыменование переменной или что-нить подобное.
          Ответить
          • чуть ниже я описал ситуацию...

            приведу псевдокод еще раз
            // c1.cpp
            const int& some_val_ref = Some_template<param>::value;

            // c2.cpp
            extern const int& some_val_ref;
            некоторый класс в жизни до main обращался к этой переменной и получал в ответ 0, при этом в main этот же код читал правильное значение...
            Ответить
            • Это не имеет никакого отношения к static const int some_val = constexpr.
              Ответить
              • я не разбирался где именно проблема... я лишь вынес урок что const int не всегда компайл тайм переменная в отличии от enum{ some_const }; которая в случае невозможности вычисления в компайл тайм, выдаст ошибку компиляции...
                Ответить
    • const засунет только в том случае в код, если на него заюзать const_cast, а так останется констатой и не полезет в рантайм, таков уж стандарт.
      Ответить
      • я использовал ссылку на эту переменную... до определенного момента из переменной читался 0, потом оказалось что она просто вычислялась позже чем я ее пытался читать... компилятор GCC 4.0 из iPhone SDK
        Ответить
        • Ну это тоже говнокодовость, нафига ссылку давать на POD тип? Очень сильно попахивает. При условии, что передача POD типов очень хорошо оптимизируется, ну а так же ссылка приводит к разыменованию переменной, что и привело к тому, что переменная покинула пределы compile-time.
          Ответить
          • одна из библиотек для линковки требовала несколько констант, которые она принимала по ссылке, типа так
            extern const int& use_some;
            extern const bool& enable_something;
            Ответить
            • Ну вот это жесть, хотя для objective c это может и в порядке вещей. Я бы пальцы вырвал такому разработчику, кто придумал передавать так данные в либу)))
              Ответить
              • это не обжектив С, это код одной старой игры которую я портировал на iPhone...
                Ответить
    • >static const int
      В стандарте до С++0х не с компилируется.
      По крайней мере майкрософсткий компилятор до 2010 студии это делать не будет.
      Ответить
      • Это Вы сейчас про какую строку?
        Инициализация статических интегральных типов возможна внутри класса.
        Ответить
        • >Это Вы сейчас про какую строку?
          Например:
          static const int count = Solution<n / 10>::count + 1
          Ответить
          • Половина шаблонных библиотек использует этот приём.
            Ответить
            • >Половина шаблонных библиотек использует этот приём.
              Зато другая и более надёжная половина библиотек использует заместо этого приёма enum.
              Ответить
        • >Инициализация статических интегральных типов возможна внутри класса.
          Конечно, только не во всех компиляторах. Например майкрософстская 2008 студия - сольёт.
          Ответить
            • Странно. Может обновления какие накачены на студию?
              И при зависимости от шаблона тоже работает?
              Ответить
              • Работает и от шаблона. Версия 9.0.30729.1 SP. Т.е. сервис пак 1 установлен.
                Ответить
      • По крайней мере со стандарта C++98 и компилится и повсеместно используется. Вот раньше вроде были проблемы кое-где.
        Ответить
  • А школьник потом не начал орать, что 1024 больше 100?
    Ответить
  • не понял смысла в макросе DECLARE_ONE_DIGIT_SOLUTION. Без него все делается шаблонами отлично.
    Ответить
    • Разверните шаблон вручную - он уйдет в рекурсию без этих макросов.
      Ответить
      • Я все понимаю, но временами надо головой подумать, а не чем-нить другим, есть и другие решения без такого изврата.
        Ответить
  • если объявлять константы через const int то где то в СPP файле нельзя будет сделать так
    int array[Solution<10>::count];
    метод с enum лишен этого недостатка...
    Ответить
            • Код в студию.

              Интересно, и как STL, а тем более Boost, где такое применяется в шерсть и в гриву, чувствуют себя на таких компиляторах?
              Ответить
                • $ grep -rw 'static const int' /usr/include/c++/4.4.3/ | wc -l
                  161
                  $ grep -rw 'static const bool' /usr/include/c++/4.4.3/ | wc -l
                  280
                  $ grep -rw enum /usr/include/c++/4.4.3/ | wc -l
                  172

                  Но немалая часть enum употреблена по делу, для перечислений, или в комментариях.
                  Ответить
                  • Не доказательство. Возможно во всех этих static const int нет инициализации в определении класса.
                    То есть в большинстве случаев может быть:
                    static const int p;
                    ,а не:
                    static const int p=5;
                    Ответить
                      • Может быть с такой:
                        //class.h:
                        class CLASS
                        {
                          static const int p;
                        };
                         
                        
                        //class.cpp:
                        const int CLASS::p=5;
                        ,а не с такой:
                        //class.h:
                        class CLASS
                        {
                          static const int p=5;
                        };
                        ?
                        Ответить
                        • Вы не поверите, но в /usr/include/c++/4.4.3/ -- только хидеры.

                          Да что я тут грепом машу -- см. 9.4.2.
                          Ответить
                          • Надо мне глянуть на STL из MS VS. По моему там конструкций в определениях классов, вида static const * = *; нет. Только через enum.
                            Жалко MS VS дома не стоит...
                            Ответить
                          • Кстати, для чего пишете ваткомом? Думал, его пик популярности прошёл...
                            Ответить
              • да, в 2008 студии такой проблемы нет... чуть позже проверю GCC...
                Ответить
    • а это так принято заворачивать жесткие выражения в препроцессор?
      Ответить
      • если что-то можно сделать в компайл тайме, это нужно сделать именно там...
        Ответить
          • не похожа... паскалисты считают что от обилия скобочек и уголков она даже выглядит круче...
            Ответить
            • да, тогда ок)
              там действительно допустимо превратить код в кусок говна ради скорости
              Ответить
              • Угу, как раз недавно играл в такую. Если персонаж на рассвете посмотрит вправо и немного вверх, игра превращается в слайд-шоу. По прошествию 3 патчей - не исправлено.
                Ответить
                  • все они одинаковые, до дедлайна говнокодят, после - не рефакторят
                    Ответить
                    • это правда... и это печально...
                      только говнокодят обычно в ноч перед дедлайном, а потом живут по принципу "работает - не трогай"...
                      обидно, что можно жить по другому, но в это мало кто верит...
                      Ответить
                • тут явно не в коде дело... где-то затесался жЫрный меш...
                  Ответить
                  • а бывает что какое-нибудь животне с дифферентом на нос бороздит поверхность холма, так что только хвост наружу торчит
                    тоже явно не в коде дело 😀
                    Ответить
                    • Тоже, бывает, что не в коде дело, а аниматор не верно указал boundary box меша или прочие параметры объекта.
                      Ответить
                      • не, чаще всего они выравниваются и резво норовят засмотревшегося PC схватить за жопу
                        Ответить
                    • в геймдеве очень много data driven кода, и иные подходы считаются очень говнокодными.
                      время программистов дороже времени геймдизайнеров и артистов, поэтому все стараются выносить из кода в данные...
                      отсюда любовь ко всяким луа, хмл, и тп...
                      Ответить
                      • желание описывать данные декларативно -- совершенно логичное
                        в хорошем энтерпрайзе тоже есть DSL
                        Ответить
  • static const int заменить на enum и
    нужна специализация только для нуля. потом last и надо выкинуть из шаблона first. вместо него ввести степень 10.
    template<const size_t n>
    struct solution {
      enum { count = solution<n / 10>::count + 1 };
      enum { sum = solution<n / 10>::sum + n % 10 };
      enum { power_10 = solution<n / 10>::power_10 * 10 };
    };
    
    template<>
    struct solution<0> {
      enum { count = 1 };
      enum { sum = 0 };
      enum { power_10 = 1 };
    };
    
      std::cout << "Number of digits: " << solution<number>::count << std::endl;
      std::cout << "Sum: " << solution<number>::sum << std::endl;
      std::cout << "Last digit: " << number % 10 << std::endl;
      std::cout << "First digit: " << (10 * number) / solution<number>::power_10 << std::endl;
    Ответить
    • Верно, специализация для 10 цифр понадобилась из-за first. Ваш вариант не работает для очень больших чисел (возможно переполнение в 10 * number) -- следует использовать number / solution<number/10>::power_10.

      Ну и использовать enum вместо static const int не нужно.
      Ответить
    • Вместо енамов, кстати, можно использовать BOOST_STATIC_CONSTANT и будет кроссплатформенность
      Ответить

Добавить комментарий

Где здесь C++, guest?!

    А не использовать ли нам bbcode?


    8