загадка (для программистов)
Aug. 8th, 2002 04:06 pmЗагадка: что напечатает приведенная ниже однострочная программа, если её запустить? Желательно отгадать, не запуская. Если никак не получится, советую хотя бы попробовать объяснить, почему она печатает то, что печатает. Кстати, компилировать и запускать надо на каком-нибудь Юниксе (почему? дополнительный вопрос).
main() { printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}
Это одна из самых любимых мной программ из числа победителей Obfuscated C Contest. Она победила в категории one-liner в 87-м году. А ещё одна программа-победительница в том же году замечательно иллюстрирует тезис статьи Дейкстры "Goto statement considered harmful":
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;}
no subject
Date: 2002-08-08 06:14 am (UTC)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
Re:
Date: 2002-08-08 06:20 am (UTC)Я пока скрою твой коммент, чтобы дать ещё другим возможность порешать.
no subject
Date: 2002-08-08 06:25 am (UTC)А вопрос, собственно, был такой - говорит ли ANSI C, что charset - всегда ASCII (в младшей половине) ?
Ибо с EBCDIC, например, этот номер не пройдёт - константу править придёцца.
Re:
Date: 2002-08-08 06:29 am (UTC)Но никто не сказал, что она обязана быть 100% ANSI C compliant.
no subject
Date: 2002-08-08 07:30 am (UTC)Видимо, нет, хотя есть устойчивое мнение, что да. Подробности тут.
Однако же
Date: 2002-08-08 06:16 am (UTC)Лошадь
no subject
Date: 2002-08-08 06:19 am (UTC)no subject
Date: 2002-08-08 06:21 am (UTC)no subject
Date: 2002-08-08 06:28 am (UTC)"unix" ;)
Re:
Date: 2002-08-08 06:30 am (UTC)no subject
Date: 2002-08-08 07:05 am (UTC)Вторая считает количество goto в файле ;)
А вторая совсем не так элегантна, как первая, но, всё равно приятно. Давно не распутывал ничего такого. Еле удержался от того, чтобы её просто запустить.
Re:
Date: 2002-08-08 07:06 am (UTC)no subject
Спасибо Вам за неё! Буду её приводить как довод против goto абитуриентам, которых С учу. Выглядит уж очень здорово!
no subject
Здесь используется "обратный" синтаксис обращения к массиву (т.е. 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)зачем это, a?
Re: зачем это, a?
Date: 2002-08-11 02:14 am (UTC)Хм
Date: 2002-08-08 06:46 am (UTC)Вот кто бы лучше ключ дал как девятый уровень пройти в веболомке, так и не допер...
Re: Хм
Date: 2002-08-08 06:52 am (UTC)Не не не....
Date: 2002-08-08 07:05 am (UTC)Вообще, я обожаю загадки
Re: Хм
no subject
Date: 2002-08-08 07:11 am (UTC)#define togt printf
#define ttgo fclose
и т.п. вплоть до ифов :)
no subject
no subject
Date: 2002-08-08 07:14 am (UTC)no subject
Date: 2002-08-08 09:41 am (UTC)