1. C++ / Говнокод #26018

    0

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    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
    #include "pch.h"
    #include <iostream>
    
    using namespace std;
    
    struct _Point {
    	double x, y, z;
    };
    
    void setPoint(_Point &, double = 0, double = 0, double = 0);
    
    void outPoint(const _Point &, char);
    
    int main()
    {
    	_Point A, B, C, D;
    	setPoint(A, 1, 5, 6.78);
    	setPoint(B);
    	setPoint(C, 8);
    	setPoint(D, 3, 4);
    
    	outPoint(A,'a');
    	outPoint(B,'b');
    	outPoint(C,'c');
    	outPoint(D,'d');
    }
    
    void setPoint(_Point &name, double a, double b, double c) {
    	name.x = a;
    	name.y = b;
    	name.z = c;
    }
    
    void outPoint(const _Point &name,char ch) {
    	
    	cout <<ch<< "(" << name.x << ", " << name.y << ", " << name.z << ")\n";
    }

    Запостил: maxrbs, 07 Ноября 2019

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

    • нахуя функции дважды дефайнить. задефайнь сразу, нехуй. она ведь не в 70+ строк
      Ответить
      • Ну бывает нисходящее программирование, а бывает восходящее. Первое это как в топике, а второе - это если сразу задефайнить.
        Ответить
        • а бывают взаимно-рекурсивные кобенации функций
          Ответить
          • #include <stdio.h>
            #include <math.h>
            
            double sqr(double x) { return x*x; } // просто возведение в квадрат
            
            double sinus(double x);
            double cosinus(double x);
            
            double sinus(double x) {
                if(fabs(x) < 2.45E-5) { // (2.45E-5)²/6 ≈ 1E-10
                    return x;
                } else {
                    return 2*sinus(x/2)*cosinus(x/2); // формула синуса двойного угла
                }
            }
            
            double cosinus(double x) {
                if(fabs(x) < 1.4E-5) { // (1.4E-5)²/2 ≈ 1E-10
                    return 1.0;
                } else {
                    return sqr(cos(x/2)) - sqr(sin(x/2)); // формула косинуса двойного угла
                }
            }
            
            int main() {
                printf("sin(π/6) = %f\n", sinus(M_PI/6));
                printf("cos(π/3) = %f\n", cosinus(M_PI/3));
                return 0;
            }


            https://ideone.com/ZdVk3b
            Ответить
            • Описка во второй функции. Исправлю:
              #include <stdio.h>
              #include <math.h>
              
              #ifndef M_PI
              #define M_PI (4*atan(1.0))
              #endif
              
              double sinus(double x);
              double cosinus(double x);
              
              double sinus(double x) {
                  if(fabs(x) < 2.45E-5) { // (2.45E-5)²/6 ≈ 1E-10
                      return x;
                  } else {
                      return 2 * sinus(x/2) * cosinus(x/2);
                  }
              }
              
              double cosinus(double x) {
                  if(fabs(x) < 1.4E-5) { // (1.4E-5)²/2 ≈ 1E-10
                      return 1;
                  } else {
                      double c = cosinus(x/2), s = sinus(x/2);
                      return (c + s) * (c - s);
                  }
              }
              
              int main() {
                  printf("sin(π/6) = %f\n", sinus(M_PI/6));
                  printf("cos(π/3) = %f\n", cosinus(M_PI/3));
                  return 0;
              }


              https://ideone.com/rR4vqP
              Ответить
              • if(fabs(x) < 2.45E-5)
                      return x;

                Первый зомечательный предел
                Ответить
              • Круто. Но не очевидно, что это устойчивый алгоритм.
                Ответить
                • Алгоритм может не сходиться, если использовать другие тождества вроде sin(x) == cos(M_PI/2 - x) или sin(x) = sqrt(1 - cos(x)*cos(x)).

                  Тут же очевидно, что на каждой итерации абсолютное значение аргумента должно уменьшаться вдвое, пока не попадёт в интервал, в котором sin(x) ≈ x или cos(x) ≈ 1.

                  Нарваться на неожиданность можно, если взять слишком низкий порог и получить underflow (денормализованный плавающий питух). Тут вроде 2.45E-5 не такая уж маленькая константа.

                  Недостаток: мы не можем гарантировать точность. В стандартной библиотеке у нас вместо косинуса и синуса многочлен с идеально подобранными коэффициентами (усечённый ряд Тейлора), вычисляющийся по оптимальной схеме (схема Горнера или типа того). Тут же, если развернуть алгоритм, получим тот же самый многочлен, однако, мы не знаем, насколько оптимален порядок вычислений. Мы можем ловить всякую фигню типа вычитания близких чисел.

                  Хотя 5 знаков после запятой получились верными. Уже неплохой результат.

                  P.S. Взял оба порога 1E-8. Считает точно, но медленно.
                  Ответить
    • Заметил, что часто преподы преподают не C++, а сишку + немножко сахарку из плюсов.

      Так что бери труп страуса за рога и учись сам, малец!
      #include <iostream>
      #include <string>
      
      class Point {
      private:
        const std::string m_name;
        double m_x;
        double m_y;
        double m_z;
      
      public:
        Point(const std::string& name, double x = 0.0, double y = 0.0, double z = 0.0)
          :m_name(name), m_x(x), m_y(y), m_z(z)
        {}
        
        const std::string& getName() const
        {
          return m_name;
        }
      
        double getX() const
        {
          return m_x;
        }
      
        double getY() const
        {
          return m_y;
        }
      
        double getZ() const
        {
          return m_z;
        }
      
        
        friend std::ostream& operator<< (std::ostream &out, const Point &p);
      };
      
      std::ostream& operator << (std::ostream &out, const Point &p)
      {
        out << p.m_name << "(" << p.m_x << ", " << p.m_y << ", " << p.m_z << ")";
        return out;
      }
      
      int main()
      {
        Point A("A", 1, 5, 6.78);
        Point B("B");
        Point C("C", 8);
        Point D("D", 3, 4);
        std::cout << A << std::endl
                  << B << std::endl
                  << C << std::endl
                  << D << std::endl;
      }
      Ответить
      • Хороший вопрос, конечно, стоит ли хранить имя в точке. Но это зависит от задачи.
        Ах да, там же в оригинале вообще
        const _Point &name

        Туда бы еще подошло что-то типа
        #define OUT_POINT(NAME) outPoint(NAME, #NAME)
        Ответить
        • #define OUT_POINT(NAME) outPoint(NAME, #NAME)
          OUT_POINT(A);
          OUT_POINT(B);
          OUT_POINT(C);
          OUT_POINT(D);
          #undef OUT_POINT

          Не сри где живёшь кодишь!
          Ответить
      • > Заметил, что часто преподы преподают не C++, а сишку + немножко сахарку из плюсов.

        Лучше б просто сишку преподавали.

        > Так что бери труп страуса за рога и учись сам, малец!

        Нет, пусть лучше берет K&R. А плюсы нахуй и впизду пусть отправляются
        Ответить
        • Всегда ржу с того, что нубов учат сразу плюсам.

          Ребенок еще итерироваться по циклу не умеет, а уже плюсы.
          Отсюда блядьт все эти system("pause")

          Кстати, плюсую про K&R. Еще есть хорошая книга с коровой от ориелли.

          Сначала надо твердо выучить сишечку, понять указатели, память, сторадж классы, линковку, вот это всё, а потом браться за плюсы. Иначе будет каша
          Ответить
          • Именно поэтому я за «PHP».
            Ответить
            • Да, в «PHP» никаких system("pause") не бывает. Зато может быть system("rm -rf /*").
              Ответить
              • vanished
                Ответить
              • Похоже, просто в "прыщах" нет такой команды:
                https://ideone.com/JSUGuY
                https://ideone.com/Ar3mx7
                Ответить
                • И правда... Тут предлагают какие-то костыли:
                  https://stackoverflow.com/questions/92802/what-is-the-linux-equivalent-to-dos-pause
                  Ответить
          • system("pause") вставляют для того, чтобы консоль не закрывалась, когда запускаешь экзэшник через гуй или "Visual Studio".
            Ответить
            • если подсистема сосноль, то ctrl + f5 не закроет
              Ответить
              • Вот именно. А при нормальном запуске из сосноли эта пауза только всё испортит.
                Ответить
                • угу
                  а как так получсется, что детей этому не учат?
                  Ответить
                  • Я же написал зачем так делают. "Visual Studio" по зелёной кнопочке открывает как "F5", а не "Ctrl+F5" (потому идут в Гугл, и находят темы с советами из 2008 года).
                    Ответить
                    • https://vscode.ru/prog-lessons/esli-konsol-zakryivaetsya-posle-vyipolneniya-programmyi.html

                      _getch - один из советов
                      Ответить
                    • Ну вот первое видео в гугле: https://m.youtube.com/watch?v=mdqVwTFMGe0
                      Ответить
                      • кстати про канал,он просто БОМБА,и только с помощью тебя я освоил ЛСНОВУ ПРОГРАММИРОВАНИЯ,спасибо иди в таком же духе....
                        Ответить
                      • Они че, ебанулись делать видео по такой хуйне? Может еще сделают видео о том, что сонсольную программу можно завершить сочетанием Ctrl+C?
                        Ответить
                        • Причём видео будет минут на 30.
                          Ответить
                        • Добро пожаловать в 2019-й год. Скоро дауны-хипстеры-говноеды совсем разучатся читать, и «man ls», следуя всеобщей моде, будет открывать в браузере получасовой видос с каким-нибудь заикающимся уёбком, который по теме знает только её название.
                          Ответить
                    • Причём так было до версии «2017», ЕМНИП. В новых версиях по-умолчанию запускается не закрывающаяся соснолька вс-ная.
                      Ответить
                    • Сиречь это проеб юзабилистов МС, которые почему-то подумали, что в студии будут писать умные программисты, а не 14-ти летние дети, котоырм на информатике задали написать программу для решения квадратного уравнения?
                      Ответить
      • Имя в точке - это уже какая-то джава...
        Ответить
      • Фу, зачем делать метода getName по ссылке?
        Ответить
        • Ааа, я консту не заметил.
          Ответить
        • Для старых крестов вполне норм. Не копировать же строку на каждый вызов.

          А в новых я за «std::string_view».
          Ответить
          • Что станет с твоим string_view, когда строка изменится?
            Ответить
            • >>> It is the programmer's responsibility to ensure that std::string_view does not outlive the pointed-to character array
              Ответить
            • Продолжение его использования будет UB'ом.
              Ответить
              • Ураа!!!!! Броманд вренулся!
                Ответить
                • Томушо скоро Новый год (http://govnokod.ru/25922)
                  Ответить
              • Я к этому и вёл. Нехуй из "getName" возвращать string_view. const string& я бы тоже не стал, проебется после уничтожения объекта.
                Ответить
                • Имхо, это зависит от использования и семантики

                  Если явно написать, что там вью, то можно и рефу вернуть.
                  Если я, к примеру, вызываю этот метод 198 раз, то нахуй мне все это копировать??
                  Ответить
                • А зачем всегда возвращать копию строки? Если тебе нужно куда-то это имя схоронить — делай «std::string pointName = point.getName();» и копируй явно. Если нужно просто однократно использовать (напечатать, хэш высчитать, сравнить) — string_view/const string& справятся идеально. А возврат std::string из подобных методов полностью противоречит главному принципу крестов: «You don't pay for what you don't use».
                  Ответить
                  • а вдруг я написал класс StringFactory который умеет создавать нужную мне строку?
                    Ответить
                    • Чего? Мы сейчас ведём речь за методы, подобные getName() — возвращающие строковое поле класса. Естественно, если тебе нужно создавать строку и передавать владение этой строкой кому-то другому, то string_view/const string& никак не подойдут.
                      Ответить
            • A typical implementation holds only two members: a pointer to constant CharT and a size.

              угадай, что будет
              Ответить

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