avva: (Default)
[personal profile] avva
Загадка: что напечатает приведенная ниже однострочная программа, если её запустить? Желательно отгадать, не запуская. Если никак не получится, советую хотя бы попробовать объяснить, почему она печатает то, что печатает. Кстати, компилировать и запускать надо на каком-нибудь Юниксе (почему? дополнительный вопрос).

main() { printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}

Это одна из самых любимых мной программ из числа победителей Obfuscated C Contest. Она победила в категории one-liner в 87-м году. А ещё одна программа-победительница в том же году замечательно иллюстрирует тезис статьи Дейкстры "Goto statement considered harmful":
#include <stdio.h>
#include <malloc.h>
main(togo,toog)
int togo;
char *toog[];
{char *ogto,   tgoo[80];FILE  *ogot;  int    oogt=0, ootg,  otog=79,
ottg=1;if (    togo==  ottg)   goto   gogo;  goto    goog;  ggot:
if (   fgets(  tgoo,   otog,   ogot)) goto   gtgo;   goto   gott;
gtot:  exit(); ogtg: ++oogt;   goto   ogoo;  togg:   if (   ootg > 0)
goto   oggt;   goto    ggot;   ogog:  if (  !ogot)   goto   gogo;
goto   ggto;   gtto:   printf( "%d    goto   \'s\n", oogt); goto
gtot;  oggt:   if (   !memcmp( ogto, "goto", 4))     goto   otgg;
goto   gooo;   gogo:   exit(   ottg); tggo:  ootg=   strlen(tgoo);
goto   tgog;   oogo: --ootg;   goto   togg;  gooo: ++ogto;  goto
oogo;  gott:   fclose( ogot);  goto   gtto;  otgg:   ogto=  ogto +3;
goto   ogtg;   tgog:   ootg-=4;goto   togg;  gtgo:   ogto=  tgoo;
goto   tggo;   ogoo:   ootg-=3;goto   gooo;  goog:   ogot=  fopen(
toog[  ottg],  "r");   goto    ogog;  ggto:  ogto=   tgoo;  goto
ggot;}

Date: 2002-08-08 06:14 am (UTC)
From: [identity profile] ex-ilyavinar899.livejournal.com
Если там определено #ifdef unix 1, то

main() { printf(&1["\021%six\012\0"],(1)["have"]+"fun"-0x60);}

main() { printf("%six\012\0",'а'+"fun"-0x60);}

main() { printf("%six\012\0",0х61+"fun"-0x60);}

main() { printf("%six\012\0","un");}

main() { printf("unix\n\0"); }

unix

Однако же

Date: 2002-08-08 06:16 am (UTC)
From: (Anonymous)
Однако же, было бы чертовски любопытно узнать, что же делает хотя бы вторая из программ. (Надеюсь, впрочем, дождаться и первой "отгадки")

    Лошадь

Date: 2002-08-08 06:19 am (UTC)
From: [identity profile] hotgiraffe.livejournal.com
Ой-ой, #include-ы поправьте пожалуйста во второй ;)

Re:

Date: 2002-08-08 06:20 am (UTC)
From: [identity profile] avva.livejournal.com
Ты знал! Ты знал! ;)
Я пока скрою твой коммент, чтобы дать ещё другим возможность порешать.

Date: 2002-08-08 06:21 am (UTC)
From: [identity profile] avva.livejournal.com
Упс ;)

Date: 2002-08-08 06:25 am (UTC)
From: [identity profile] hotgiraffe.livejournal.com
Кстати, очень забавные вещи происходят, когда пишешь коммент на коммент, а того в это время скринят.

А вопрос, собственно, был такой - говорит ли ANSI C, что charset - всегда ASCII (в младшей половине) ?
Ибо с EBCDIC, например, этот номер не пройдёт - константу править придёцца.

Date: 2002-08-08 06:28 am (UTC)
From: [identity profile] anton.livejournal.com
Это просто на самом деле, только запутано.
"unix" ;)

Re:

Date: 2002-08-08 06:29 am (UTC)
From: [identity profile] avva.livejournal.com
Не помню, говорит или нет.
Но никто не сказал, что она обязана быть 100% ANSI C compliant.

Re:

Date: 2002-08-08 06:30 am (UTC)
From: [identity profile] avva.livejournal.com
Хорошо, а вторая программа? ;)

Date: 2002-08-08 06:30 am (UTC)
From: [identity profile] sobaker.livejournal.com
unix - макрос. Равен 1.

Здесь используется "обратный" синтаксис обращения к массиву (т.е. s[3] == 3[s])

&unix["\021%six\012\0"] дает адрес символа в массиве, следующего за первым (так мы пропускаем красивый \021).

\012 - это \n в восемеричной записи. Т.е. формат-строка имеет вид "%s ix\n" (пробел вставил для наглядности).

Аргумент printf'а: адрес строки "fun", к которому прибавлено число 'a'-0x60 ('a' получили из (1)["have"]). Очевидно, что 'a'-0x60 = 97-96 = 1. Т.е. не "fun", "un".

Итого: printf("%six\n", "un"). Иначе говоря - "unix".

Получил удовольствие :)

Re:

Date: 2002-08-08 06:31 am (UTC)
From: [identity profile] avva.livejournal.com
Всё правильно, здорово ;) раскрываю первый коммент [livejournal.com profile] ilyavinarsky, к-й тоже правильно решил.

Хм

Date: 2002-08-08 06:46 am (UTC)
From: [identity profile] barsen.livejournal.com
Странные загадки... Ответ и на первую и вторую находится на гугле с полпинка, соответственно смысла нет их публиковать... Ну, по крайней мере, в разделе загадок.
Вот кто бы лучше ключ дал как девятый уровень пройти в веболомке, так и не допер...

Re: Хм

Date: 2002-08-08 06:52 am (UTC)
From: [identity profile] ex-innin997.livejournal.com
в разделе загадки (http://www.livejournal.com/users/zagadki/), как вы красиво сказали, это я опубликовал ссылку на постинг [livejournal.com profile] avva так что не надо на него наезжать :)

Не не не....

Date: 2002-08-08 07:05 am (UTC)
From: [identity profile] barsen.livejournal.com
Я не наезжал... Само по себе это разумеется интересно
Вообще, я обожаю загадки

Date: 2002-08-08 07:05 am (UTC)
From: [identity profile] anton.livejournal.com
Брр...
Вторая считает количество goto в файле ;)

А вторая совсем не так элегантна, как первая, но, всё равно приятно. Давно не распутывал ничего такого. Еле удержался от того, чтобы её просто запустить.

Re:

Date: 2002-08-08 07:06 am (UTC)
From: [identity profile] avva.livejournal.com
Браво ;)

Date: 2002-08-08 07:11 am (UTC)
stas: (Default)
From: [personal profile] stas
В первой для красоты эксперимента хорошо бы сделать goto.h, в котором, соотв.,
#define togt printf
#define ttgo fclose

и т.п. вплоть до ифов :)

Date: 2002-08-08 07:11 am (UTC)
stas: (Default)
From: [personal profile] stas
во второй, тоиссь...

Date: 2002-08-08 07:12 am (UTC)
From: [identity profile] anton.livejournal.com
Распутывание её, правда, тупая задачка, так что не за что!

Спасибо Вам за неё! Буду её приводить как довод против goto абитуриентам, которых С учу. Выглядит уж очень здорово!

Date: 2002-08-08 07:14 am (UTC)
From: [identity profile] anton.livejournal.com
Cтройность потеряется. Она сейчас выглядит хорошо.

Re: Хм

Date: 2002-08-08 07:17 am (UTC)
From: [identity profile] anton.livejournal.com
А смысл искать ответы гуглем, если можно решить. Странное занятие получается - искать ответы на загадки, за разгадку которых ничего, кроме удовольствия от решения их получить не получится.

Date: 2002-08-08 07:30 am (UTC)
From: [identity profile] cema.livejournal.com
говорит ли ANSI C, что charset - всегда ASCII (в младшей половине) ?

Видимо, нет, хотя есть устойчивое мнение, что да. Подробности тут.

Date: 2002-08-08 09:41 am (UTC)
From: [identity profile] cema.livejournal.com
В этом варианте предполагается ASCII. Легко переделать на общий случай.

зачем это, a?

Date: 2002-08-09 10:34 am (UTC)
From: [identity profile] zc2.livejournal.com
Интересно, в каких случаях практически может пригодиться обратная нотация доступа к массиву? Или только для постановки подобными задачками в тупик начинающих программистов?.. ;-)

Re: зачем это, a?

Date: 2002-08-11 02:14 am (UTC)
From: [identity profile] avva.livejournal.com
Практически не может пригодиться, но педагогический смысл в ней есть. Настоящий программист на C должен понимать, что a[b] - это всего лишь синтаксический вариант *(a+b), что эти две формы абсолютно идентичны. Форма b[a] напоминает об этом.

December 2025

S M T W T F S
  123 4 56
78 9 10 11 1213
1415 1617181920
21 22 23 24 2526 27
28293031   

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Dec. 28th, 2025 10:29 am
Powered by Dreamwidth Studios