Школоло / Говнокод #27889 Ссылка на оригинал

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
Program print_numbers_twice;

Procedure give(p: pptrint);
begin
	if pptrint(p^) <> nil then begin
		give(pptrint(p^));
		writeln((p-1)^)
	end
end;

Procedure take;
var n: ptrint;
begin
	if not SeekEof then begin
		read(n);
		take
	end else begin
		n := (pptrint(@n)+1)^;
		give(pptrint(n));
		give(pptrint(n))
	end
end;

Begin
	take
End.

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

Очень простая и короткая программа. Я думаю, вам не составит труда понять, как она работает. Пишите в комментариях!

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

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

    • P.S. В библиотеке Фрипескаря описан, оказывается:
      type
       PtrInt = LongInt;
       PPtrInt = ^PtrInt


      Целое размером с указатель, как ptrdiff_t в сишном <stddef.h>
      Ответить
      • А как используется тот факт, что ptrint хранит число, в которое может поместиться указатель? Или он используется без семантики, просто как первый подвернувшийся под руку целочисленный?
        Ответить
    • Боюсь, что придётся смотреть ассемблерный листинг, чтобы понять.

      Вот тут пахнет:
      n := (pptrint(@n)+1)^;


      Набиваем стек, а потом его затираем введённым с консоли значением.
      Ответить
      • Ну хоть один комментарий по делу. Но тут происходит присваивние локальной переменной n, так что ничего страшного нет и ничего не ломается. Вся запись происходит только в локальную переменную процедуры, а это допустимо.
        Ответить
      • Ну или хотя бы как устроена конвенция вызовов функций. Кажется, он там проходит по цепочке сохраненных BP... а так - да, ничего страшного. Всегда так делаю.
        Ответить
        • > цепочке BP

          Именно поэтому я за FPO, чтобы у царей не было желания шариться по стеку.
          Ответить
          • Отменили уже твой FPO. Регистров уже никому не жаль (чай не под 486 пишем) а раскручивать стеки без символов иногда нужно, чтобы хотябы понять в каком районе обосралось примерно.

            Теперь все собрано с указателем рамки
            Ответить
              • Я читал в the old new thing, что начиная с Vista MS собирает свои продукты с фрейм поинтером, потому что экономить BP уже не актуально.

                Ты ведь можешь сам это проверить как-то взяв MSную dllку?
                Ответить
                • А теперь сходи и отключи его сам для своих виндовых дллок под х64, собранных в msvc...
                  Ответить
                  • ой, за x64 не скажу, там может всё иначе быть
                    А нахуй он там? Там же регистров как у дурака фантиков
                    Ответить
                    • х64 соглашения заточены на пирфоманс, всё через регистры.

                      А тут писать на стек сраный rbp, который кроме отладчика (без символов) да аллоки никто не юзает. Вот и выбросили.
                      Ответить
                      • 1. BP нужно сохранять, без него хуй адресуешь локальные переменные.
                        2. Мы научилось адресовать их от SP, BP заюзаем под что-то другое
                        3. У нас стало больше регистров, давайте опять юзать BP
                        4. Зачем нам BP? Давайте от него откажаемся
                        [вы находитесь здесь]

                        Алсо, если я пишу асм руками, то наверное я хочу frame pointer, иначе отступы будут неочивидны? Или современные асмы все за меня посчитают?
                        Ответить
                        • Я руками с фреймпоинтером пишу, так проще.

                          Возможно какой-нибудь fasm и умеет об rsp считать... Но маловероятно т.к. ему придётся понимать инструкции, а не тупо их конпелять.
                          Ответить
                          • Зато если руками писать без BP, то это заставит тебя сначала все спланировать, потому что спонтанное "ой, а добавлю-ка я переменную еще одну" может превратиться в адскую боль
                            Ответить
                            • > переменную

                              Да хуй с ними, с переменными, они на х64 обычно все в регистрах...

                              Проблема в том, что любой пуш и у тебя rsp поехал.

                              > BP

                              А может я хочу об rdi базироваться? Или об r11.
                              Ответить
                              • Я никогда не писал под x64 руками. Ты прям все-все пельменные в регистрах хранишь? все тридцать штук?

                                А зачем тогда тебе что-то пушать тогда? Чтобы кольнуть 32х битное говно?

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

                                  Ну например чтобы callee-saved регистр начать юзать.

                                  > зачем

                                  Для самовыражения и уникальности.
                                  Ответить
                                  • >Ну например чтобы callee-saved регистр начать юзать.

                                    а, типа ты папин регистр припрятал, поюзал, и вернул обратно, да?

                                    чото я сразу не сообразил, так же обычно всегда и делали. были даже ПУША и ПОПА для этого.

                                    >Для самовыражения и уникальности.
                                    чувак, ты пишешь на асме в 2021, ты и так уникален
                                    Ответить
                                  • как ты из 64 вызываешь 16? разве не надо там v86 настраивать (который вроде в лонгмоде не работает)?

                                    или у тебя 16bit protected, как в 286/win3.11?

                                    И зачем? Биосы железок дергать?
                                    Ответить
                                    • Отключаю всё обратно и ухожу в труъ реалмод...

                                      > бивисы

                                      Угу. Легаси-хуегаси.
                                      Ответить
                                      • "перезагрузить компьютер в режиме эмуляции MS-DOS" (c)

                                        Useless fact: в двойках нельзя было вернуться из протектд режима в реальный никак кроме колд ресета. Я у Гука читал.

                                        Но в тройке уже починили
                                        Ответить
                                        • Вроде не колд, а достаточно без очисток памяти, кокойто меджик надо записать по волшебному адресу. Надо было писать label far
                                          Ответить
          • Я не помню соглашение, но наверное да. Иначе дебаггеру будет неудобно. А эти фреймы в основном ему и нужны.
            Ответить
  • Как же я не люблю структуро-указателеёблю в олимпиадочных прогах!..
    Поубивал бы.
    Ответить
  • - Я люблю программировать.
    - Покажи.
    - ...
    - Ты больной ублюдок.
    Ответить
      • помоему питон уже окончательно заменил перла в амплуа "пламбер ленгвидж" в линуксе
        Ответить
          • P.S. В одной конторе был классный момент с питонопарашниками, которые отлаженные, протестированные в CI и документированные (там network diagram аска-артом была в комментах) m4 кружева для генерации некой конфы решили заменить на пухтон. Мой аргумент был: для простого скрипта вы понатащили пять зависимостей, которые требуют ебли с какими-то ``virtualenv'', ``pip'' и прочей хернёй, если она сломается, вы будете ебаться с ней сами.
            Она конечно же сломалась, и утащила за собой load-balancer'ы в проде. Помогать чинить это говно я конечно им не стала.
            Сисадмин питонист — горе в семье.
            Ответить
              • да-да, только ПХП на CI не хватало
                Ответить
                  • не думаю, что пыхеры могут в CI.

                    Разные культуры развиваются с разной скоростью. У кого-то компьютеры, а у бушменов мезолит.

                    Пыхеры только-только юнит-тесты освоили, лет через двадцать и до CI доберутся
                    Ответить
          • ну как нет, когда уебунта уже от него зависит, а когда я говорю коллегам про перл, то у них такие лица бывают, словно я предложил им пописать на Visual Basic под WinME
            Ответить
  • Как видишь, местное отребье применило свой старый, испытанный прием: пустилось завивать лесенку из оффтопных комментов, чтобы отклонить обсуждение и скрыть за плоскими шуточками ебаный стыд от своей некомпетентности. В мою бытность они тоже так поступали, а потом удивлялись, почему я столь нещадно громлю их оффтопы.
    Ответить
  • Сломал твою программу, проверь:
    procedure lom(s: string);
    begin
    	writeln(s);
    	take
    end;
    
    Begin
    	lom('lomayu')
    End.
    Ответить
  • В таком виде она должна вывести одно лишнее число, которого не было на входе.
    Ответить
          • Так я правильно угадал или нет? Я просто не запускал твою версию.

            Если правильно — сам думай, программа на то и написана. Если нет — ну значит я ошибся где-то.
            Ответить
          • Не, на самом деле выводится другое число — это адрес строчки lomayu. Видимо строка передалась в процедуру по ссылке.
            Ответить
  • Блядь, как всё сложно... Неудивительно, что в современности на этом языке больше никто не пишет.
    То ли дело «Python»:
    numbers = []
    try:
        while True:
            numbers.append(int(input()))
    except EOFError:
        pass
    
    
    for i in range(2):
        for num in numbers:
            print(num)
    Ответить
    • Ещё в турбопаскалевском «Turbo Vision» были коллекции (да, там был модуль Objects с невизуальными объектами), а в «Delphi» ещё добавили динамические массивы. Во «Фрипаскале» всё это есть.
      Ответить
    • В паскале тоже так можно, если взять динамический массив — но это будет слишком просто и скучно.
      Ответить
    • Блядь, как всё сложно... Неудивительно, что в современности на этом языке больше никто не пишет.
      То ли дело «Python»:
      import sys
      
      numbers = [int(line) for line in sys.stdin]
      
      for num in numbers * 2:
          print(num)

      Прости, Царь, за дублирование дублирование массива.
      Ответить
      • Да начнётся специальная олимпиада!
        import sys;print(*[*map(int,sys.stdin)]*2,sep='\n')

        Условиям оригинальной задачи первый коммент не соответствует — в нём числа надо вводить по одному на строку, а не через любые пробельные символы — но да ладно, раз уж начали так, то похуй.
        Ответить
        • Да и вообще, нахера нам кастить в инт?
          import sys;print(*[*sys.stdin]*2)
          Ответить
          • Ну не. Пили честный эквивалент через анализ бектрейса.
            Ответить
            • Ну ладно.
              import sys
              import threading
              
              
              def give(frame):
                  if frame is None or frame.f_code.co_name != 'take':
                      return
              
                  give(frame.f_back)
                  print(frame.f_locals['n'])
              
              
              def take():
                  try:
                      n = int(input())
                      take()
                  except EOFError:
                      frame = sys._current_frames()[threading.get_ident()].f_back
                      give(frame)
                      give(frame)
              
              
              def main():
                  take()
              
              
              if __name__ == '__main__':
                  main()
              Ответить
              • Оно же берёт строками, не отдельными символами.
                Надо ещё split сделать.

                И зачем в инт переводить?
                Ответить
                • > Оно же берёт строками, не отдельными символами.
                  Об этом я в примечании выше написал. Лень ебаться с этими вашими сплитами (надо не просто сплит, а сплит по \s: «Питон» соснул).

                  > И зачем в инт переводить?
                  Для коньсистентности.
                  Ответить
  • Перевёл на "Си":
    #include <stdio.h>
    #include <stdint.h>
    
    void give(intptr_t *p, int count)
    {
    	if (p != NULL && (intptr_t*)*p != NULL && count != 0) {\
    		give((intptr_t*)*p, count -1);
    		printf("%d\n", (p[-1]));
    	}
    }
    
    void take_(int count)
    {
    	intptr_t n;
    	if (!feof(stdin)) {
    		scanf("%d", &n);
    		take_(count + 1);
    	} else {
    		n = (&n)[1];
    		give((intptr_t*)n, count);
    		give((intptr_t*)n, count);
    	}
    }
    
    void take(void) {
    	take_(0);
    }
    
    int main(void)
    {
    	take();
    	return 0;
    }
    Ответить
    • Молодец, а теперь собери под 64 бита с оптимизацией с помощью gcc.
      Ответить
        • Это из той же группы требований что и
          * Отключить интернет во время установки.
          * Установочный путь не должен содержать пробелов.
          * Собирать только GCC 3.4.6 с этими флагами и никакими другими.
          * Устанавливать можно только на диск C.
          * В региональных настройках необходимо поставить десятичным разделителем точку.
          * В настройках рабочего стола включите Aeroю
          * Программу нужно запускать от администратора.
          * Шиндовс должен стоять исключительно в С:\Windows.
          ¿
          Ответить
            • При установке сторонней программы, системный антивирус автоматически отключается. Единственные две причины деактивировать его, на наш взгляд, это повышение производительности ПК или предотвращение случайных блокировок нужных файлов, которые антивирусу показались опасными.
              Ответить
                  • Но ведь сейчас антивирусы и вправду не нужны. Они были нужны в эпоху DOS и Windows 95-98.

                    Сейчас и вирусов-то почти нет. Кругом только трояны.
                    Ответить
                    • Ну дык и антивирус сейчас -- это не просто сканер файлов по сигнатурам, а фаервол и IDS.

                      Да и по сигнатурам они известных троянов вполне так выпиливают.
                      Ответить
                        • Который тебя голой жопой в инет выставит, если ты случайно не ту кнопку при подключении к сети нажмёшь?
                          Ответить
                          • ну так ты не забывай делать ``Get-NetConnectionProfile`` же
                            Ответить
                              • Ну вот дебиан вообще по умочланию пустой и с политикой ACCEPT.

                                Но просто прыщи можно выстаавить в Инет без файра, им ничего не будет, а у винды анонимные петухи уже через пару минут начнут щупать твои пайпы через SMB
                                Ответить
                          • Кстати, вот пример поедания говна.


                            Прыши:
                            iptables -I INPUT --src=1.2.3.4 -j ACCEPT

                            винда
                            $rule = New-NetFirewallRule -Name "foo -DisplayName  "bar"
                            $rule | Get-NetFirwallAddressFilter | Set-NetFirewallAddressFilter -RemoteAddress 1.2.3.4


                            Пирдолинг заказываои?
                            Ответить
                          • Купил сдуру "Агнитум" коробошный, когда он только-только засветился в Интернет. Он тогда стоил около семисот рублей. Установил на "Висту", поигрался - понял, что говно, - снёс.
                            700 кровных - на ветер. Коробка до сих пор где-то валяется.
                            Ответить
                        • Файерволл не нужен.
                          В одной очень серьезной проге на которой сидит вся отчетность России используется indy, COM и прочие устаревшие технологии. Прога эта стоит охулион рублей.

                          В доке черным по белому писано:
                          Для работы приложения требуется отключить антивирус, файерволл и брандмауэр.
                          На делфи, кстати.
                          Ответить
                          • Скажу по секрету, что программа от компании Криста и называется АС Статистика.
                            Ответить
        • -fno-omit-frame-pointer не поможет кста вместо отключения оптимизации?
          Ответить
    • Как-то коряво по-моему. Зачем лишняя процедура? Зачем вообще счётчик?
      Ответить
        • А откуда моя изначальная программа знает, сколько чисел ввели, по-твоему?
          Отдельный счётчик не нужен.
          Ответить
          • А почему если твою процедуру вызвать из другой, она выводит лишние числа?
            Ответить
            • В документации к процедуре не сказано, что её можно вызывать не из main. Так что всё ок.
              Ответить
              • Проапдейтил инструкцию.

                * Отключить интернет во время установки.
                * Установочный путь не должен содержать пробелов.
                * Собирать только GCC 3.4.6 с этими флагами и никакими другими.
                * Устанавливать можно только на диск C.
                * В региональных настройках необходимо поставить десятичным разделителем точку.
                * В настройках рабочего стола включите Aeroю
                * Программу нужно запускать от администратора.
                * Шиндовс должен стоять исключительно в С:\Windows.
                * Вызывать только из main.
                * Не засирать стек посторонними данными.
                Ответить
                • > 3.4.6

                  Мутабельных литералов захотелось? Или что там закопали в том районе?
                  Ответить
                • Имя пользователя не должно начинаться на 'u' или 'x'.
                  Ответить
                  • Чёрт! Я обычно в Винде ставлю имя пользователя «user», чтобы не ломать голову.
                    Ответить
                • После вызова моей функции лучше сделать sleep на пол секунды, чтобы у планировщика было время все подчистить
                  Ответить
                  • Перед вызовом функции нужно сделать форк, а после -- завершить процесс.
                    Ответить
                    • напоминает ``vfork()``, где ребенок должен вести себя правильно, чтобы случайно папку не завалить
                      Ответить
                        • на пуповине висит, скажем так

                          Вообще хуевый, негативный вызов. Лучше им не пользоваться
                          Ответить
                          • > не пользоваться

                            Почему? Джве функции подряд не так сложно написать...
                            Ответить
                            • Наскока я помню, vfork запилили до страничной адресации еще, потому что без коровы было ОЧЕ дорого каждый раз копировать (как делал обчный fork), потому сделали такую лоу левел парашу

                              Поскоку теперь у всех (кроме j123123) есть MMU и COW (ха-ха, я родил каламбур) то смысла в вфорке мало
                              Ответить
            • Вот потому и выводит, что использует глубину стека вызовов вместо счётчика.
              Ответить
      • Дополнительную функцию можно опустить. Я просто убрал странную необходимость всегда передавать ноль, и заодно показал, что функция работает корректно в не зависимости откуда её вызвали.
        Ответить
        • У меня у первой процедуры вообще нет параметров, а у второй только один. На C это можно при желании переписать один-в-один и будет работать.
          Ответить
            • Уже давно переписал и проверил. Получилось примерно то же самое, что выше, но более кратко и без лишних параметров.
              Ответить
          • > будет работать

            Ну такое... Царские Лямбды тоже работали в конкретных условиях на конкретном конпеляторе. Очень тонкий лёд.
            Ответить
        • Оно ещё и некооректно роботает если в конец пробелов добавить.

          Да, надо было в инт кастить
          Ответить
      • Особенно, после того, как понажимают клавиши, на которых обтер пальцы инкубатор мной заселенный
        Ответить

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

Семь раз отмерь — один отрежь, guest!

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


    8