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

    +181

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    int maxOf5(int a, int b, int c, int d, int e) {
            int arr[5];
            arr[0] = a;
            arr[1] = b;
            arr[2] = c;
            arr[3] = d;
            arr[4] = e;
            bubbleSort(&arr, 5);
            return arr[0];
    }

    no comments...

    Запостил: wh_, 22 Декабря 2010

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

    • настолько прямолинейно, что даже изощренно
      Ответить
    • Ни прибавить, ни убавить!
      Ответить
    • показать все, что скрытоГде-то тут была эпичня тема, где один из коментаторов так и предлагал искать максимум (только не пузырьковым сортом, а встроенным). Когда ему сказали, что он теряет не только константу, но и порядок, он назвал всех байтоёбами.
      Ответить
      • не экспоненту а логарифм

        разлогиниться забыл, лол
        Ответить
        • > Когда ему сказали, что он теряет не только константу, но и порядок,

          А что, логарифм уже не считается? Его можно тратить как угодно?
          Ответить
          • в треде было просирание логарифма, и причитание что константу уже просрали

            я только что 15 минут потратил, чтобы выяснить, надо ли заменять ReallocMem на пару FreeMem/GetMem, любого байтоёба уделаю :-Р
            Ответить
        • Кстати, как ты определил, что это не Компренда писал? Слишком матанно и безматово?
          Ответить
          • этож давнишний тред, и словечки олдовые

            и да, откуда уэб обезьяне знать про асимптотику
            хотя "порядок" звучало подозрительно
            Ответить
    • Мне, вот, очень интересна конструкция >bubbleSort(&arr, 5).
      &arr возвращает адрес arr. Этот тип похож на int**, только он ещё содержит явное число элементов int*[5].
      Вопрос в том... Что же принимает bubbleSort?
      От меня этот момент как-то ускользает...
      Ответить
      • Принимает массив по ссылке (то есть по сути передаётся указатель на массив, в котором информации о кол-ве элементов массива нету) и кол-во элементов массива.
        Ответить
        • мутатор по-нашему
          Ответить
        • Понимаешь, arr -- это указатель на массив из N объектов типа T, где N=5. Он уже указатель. А вот &arr -- это адрес указателя.
          В стандарте есть два типа массивов array of N type T и array of unknown bound type T, последний точно определяется указателем, а вот первый неким указателем с длиной. И так получается, что адрес указателя не конвертируется в адрес указателя с диной. Хотя сами указатели на массивы приводятся легко к указателю.
          То есть, неявно передать адрес указателя с длиной, значит вызвать ошибку преобразования типов. Так оно кажется.
          Я попробовал сообразить... И просто не нашёл такого прототипа bubbleSort, который не вызвал бы ошибку типа при передаче &arr.
          Ответить
          • &arr - это указатель на arr.
            Это просто передача int*

            Про передачу по ссылке я фигню сказал, иначе было бы написано sort(arr без амперсанда.
            Ответить
            • int aInt = 0; int* aPtr = &aInt; Это вот ясно. Здесь оператор адреса применяется верно, чтобы получить адрес переменной и положить адрес в указатель. Но! int aIntArr[1] = {0}; int* aPtr = &aIntArr; -- это провал, ошибка, ill-formated; Потому что aIntArr -- уже указатель, а оператор адреса выдаст уже адрес указателя, то есть получается что-то вроде int**.
              Если бы "бубле" имело простой прототип bubbleSort(int[],int), то вызов выглядел бы так: bubbleSort(arr,int);

              Вот я и не понимаю... Что за "бубле-то" должно быть, чтобы ему &arr отдавать...
              Я склоняюсь к тому, что для массива, который объявлен с явным числом элементов оператор получения адреса указателя -- бессмыслица.
              Ответить
          • > И просто не нашёл такого прототипа bubbleSort, который не вызвал бы ошибку типа при передаче &arr.

            void bubbleSort(void* a, ptrdiff_t b);
            Не?
            Ответить
            • да
              Ответить
            • Это потребует явного каста типа, с void* нельзя работать.
              Ответить
              • Ну тогда int* a.
                Передача указателя на массив уже разрешена без каста.
                Ответить
                • В int* a нельзя положить &arr.

                  Я, конечно, не знаю, как это может восприниматься разными компиляторами, но не должно... Теоретически &arr и arr -- это разные вещи. То есть в bubbleSort(int*,int) не получится без явного каста подпихнуть &arr. Конечно, вы всегда можете сделать аналогично операции с void*: reinterpret_cast<int*>(&arr), но это уже говорит о пробеле на этапе проектирования, который привёл к "шву" на этапе конструирования.

                  Я продолжаю придерживаться позиции, что смысла в &arr просто нет никакого, нужно было передавать arr.
                  Ответить
                  • Как нельзя?!
                    int* - это тип такой, "указатель на инт".
                    &i - это указательнь на конкретную переменную.

                    > Теоретически &arr и arr -- это разные вещи.

                    Это-то причём?
                    Похоже ты знаешь С ещё хуже, чем я.
                    Ответить
                    • Ещё раз
                      В выражении int arr[5]; arr -- не int, а что-то другое, что приводится неявно (по стандарту) к int*. Потому &arr -- это уже адрес адреса переменной типа int. Что-то похожее на int** (но не оно). Положить int** в int* нельзя. При этом и &arr положить в int** тоже нельзя.
                      Ответить
                      • > Потому &arr -- это уже адрес адреса переменной типа int.

                        Да.

                        > Что-то похожее на int** (но не оно).

                        Не оно, да. Это int*.
                        ЛОЛ.
                        Ответить
                        • То есть по-вашему адрес адреса -- это int* ? То есть, если я разименую адрес адреса, один раз, то сразу получу int?
                          Вам не кажется, что если прямая операция адресации выполнена два раза, то обратная операция разименования тоже должна быть выполнена дважды?
                          Ну... На худой конец, что ли, попробуйте скомпилировать у себя код вида:

                          int arr[1] = {0};
                          int * intPtr = &arr;

                          Я уж и на знаю, что ещё сделать, чтобы вы увидели разницу.
                          Ответить
                          • > То есть по-вашему адрес адреса

                            Где тебе тут привиделся адрес адреса?
                            Я вижу только адрес массива. Массив - это не указатель. Это область памяти, в которой лежат несколько переменных подряд. А в функцию передаётся указатель на эту область памяти.
                            Короче, заканчивай ПХП защищать, плохо влияет.
                            Ответить
                            • >Где тебе тут привиделся адрес адреса?

                              Массив действительно не является указателем, это бесспорно. Но что такое переменная arr? Так вот, переменная arr -- это "что-то", что в программе представляет собой абстракцию массива. Однако, согласно стандарту, эта абстракция приводится в указатель на первый элемент при операциях над ней. Так вот положено в C++.
                              Что есть &? & -- это оператор, который будучи применён к переменной возвращает адрес этой переменной в памяти.
                              Что же будет, если мы напишем &arr?
                              arr неявно превратится в указатель на первый элемент массива, после чего от этого указателя будет взят адрес. То есть, это уже (в общем случае) не адрес первого элемента, а адрес указателя, который содержит адрес первого элемента.
                              Адрес адреса...
                              Ответить
                              • ваше упорство и прямолинейность меня поражают. я так вдохновился, что даже скомпилил ваш код
                                int arr[] = {0};
                                int (*intPtr)[1] = &arr; 
                                int *intPtr2 = arr;
                                if(intPtr[0]==intPtr2) std::cout<<"win, at last";
                                Ответить
                                • Вы присвоили все типы абсолютно точно без единого кастинга.
                                  Вы взяли адрес arr и положили его в первый элемент массива адресов.
                                  В строке два левое выражение имеет тип int*[1], как и правое &arr, а вовсе не int*, ага.

                                  А я код писал, где была попытка положить &arr в int*, как предлагал TarasB.
                                  Ответить
                                • Прошу прощения, оговорился. Конечно же не массив адресов, а адрес массива. Скобки стоят. Массив адресов не принял бы &arr, потому что это адрес массива, конечно же.
                                  Ответить
                                  • о, как раз для вас в интернетах нашлось
                                    "passing pointers by reference is so C++"
                                    Ответить
                                    • Да, у меня С++ головного мозга. Я, собственно, и не скрываю. :-p
                                      Ответить
                              • >Массив действительно не является указателем, это бесспорно.

                                Смотря где.
                                Ответить
                            • В Си массивы всегда передаются по адресу. Поэтому arr это уже адрес, а &arr - адрес адреса.
                              Ответить
                • И сразу получить по рогам на amd64 системе. Блин ну когда же все выучат, что для указателей нужно не int* и прочее юзать, а ptr_diff типы?
                  Ответить
                  • Почему?

                    Тоесть я при передаче любого указателя должен использовать ptrdiff_t ?
                    Ответить
                    • Не совсем понятно, что имел в виду Sauron, потому что http://www.cplusplus.com/reference/clibrary/cstddef/ptrdiff_t/
                      Ответить
    • так а в чем говно?

      на мелких N bubble sort более эффективен чем quick sort.

      это наверное самая читабельная реализация какую только и можно придумать.
      Ответить
      • Говно в поиске максимума через сортировку. Или это не очевидно?
        Ответить
        • бля. я тормоз. ну да. естественно. попутал с просто сортировкой..........
          Ответить
    • А сортировка еще похоже по убыванию идет.
      Ответить
    • лол. так много обсуждений на тему "&arr" vs. "arr".

      народ и не улавливает что "&arr" и "arr" имеют тот же самый эффект и тот же самый тип. в оригинальном С "&arr" было ошибкой (метка/имя массива уже есть по определению указатель; ассемблерщики должны улавить откуда ноги у синтаксиса растут). но народ просто постоянно на это спотыкался, почему и разрешили в языке "&arr" и оно аналогично "arr" и есть указатель на массив/первый элемент массива.

      ЗЫ та же самая фигня и про указатели на функции: имя функции есть указатель, и &func_name просто синоним введенный для читабельности.
      Ответить
      • Не встречал в стандарте С++ утверждения о равенстве типа адрес от указателя на массив и самого указателя на массив.

        И специально попытался крутануть код в MSVC++, известен он свой "нестандартностью", результат тот же был: ошибка кастинга типа.

        Это новшество 2011го стандарта будет?
        Ответить
      • опять выходишь на связь?

        void sort(int *arr, int size) {}
        void func() {}

        int _tmain(int argc, _TCHAR* argv[]) {
        int arr[5] = {0};
        cout << typeid(arr).name() << endl; // int [5]
        cout << typeid(&arr).name() << endl; // int (*)[5]
        cout << typeid(func).name() << endl; // void __cdecl (void)
        cout << typeid(&func).name() << endl; // void (__cdecl*)(void)
        sort(arr, 5); // correct
        sort(&arr, 5); // ill-formed
        return 0;
        }
        Ответить
        • Да, вот, кстати, я не догадался... Можно было typeid посмотреть.
          Ответить
          • Как бы еще в голом си такое посмотреть.
            Ответить
            • C менее жёстко типизируемый. Он, скорее всего, произведёт неявно преобразования типа указателей и работать даже будет, потому что реального указателя на массив при объявлении <type> <name>[N]; не существует и операция адреса вернёт адрес первого элемента.
              Ответить
      • Они численно равны, но разных типов
        Ответить
    • Я best!
      Ответить

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