программа-самовывод

loks-po

Зачем нужна в народном хозяйстве программа-самовывод (хотя, может быть я неправильно называю ЭТО). Я часто встречал их примеры на различных форумах как изящное, но не очень применимое на практие явление. Что тренирует создание таких программ и вообще, как это возможно. Можно пример из паскаля? С++/С я не знаю, но прочитать программу смогу - т.ч. можно и на С...
Заранее спасибо.

anzakaznov

Что тренирует создание таких программ?

ничего
ну -- максимум -- умение работать с динамической памятью и циклами %)

mirt1971

А зачем там динамическая память?

anzakaznov

ну да
можно и без неё
можно и статическим массивом
просто я так привык

vall

это кажется называется "интроспективная программа"
видел сайтик с подборкой таких прог на сотне языков, я думаю гугл поможет.

Papazyan

Они обычно представляют из себя массив строк программы + вывод этого массива на экран. Единственная сложность со строками - символы '"' нужно выводить по особому. В разных языках это решается по разному. В С/C++ можно вывести код этого символа.

gopnik1994

массив - это излишнее усложнение
я, когда баловался этим, обошелся 2-мя строковыми переменными..

anzakaznov

хм
а как?
разве что на си с использованием служебных символов...
и то хз

gopnik1994


const q=#39;var s,t:String;begin s:='const q=#39;var s,t:String;begin s:=';t:=';Writeln(s,q,s,q,#59#116#58q,t,q,t);end.';Writeln(s,q,s,q,#59#116#58q,t,q,t);end.

oleg_mcp

2 строковые переменные - это массив из двух строк. Твоя программа по смыслу принадлежит именно к этому типу, а большие массивы возникают из-за того, что программы занимают несколько строчек для красоты и понятности. Были бы интересны другие возможные варианты.

loks-po

Угу...
а тогда какой аутпут у вот этого кода:

const q=#39;var s,t:String;begin s:='const q=#39;var s,t:String;begin s:=';t:=';Writeln(s,q,s,q,#59#116#58q,t,q,t);end.';Writeln(s,q,s,q,#59#116#58q,t,q,t);end.


Он в точности повторяет приведенный код?
Я не программер - меня этому не учили и поэтому у меня в голове не укладывается, как можно передать код, без того, чтобы упустить хотя бы один writeln
Видимо я просто недогоняю...

anzakaznov

ну скомпиль да разберись!

Elina74

Есть на С. Она не в пример больше вышенаписанных:


#include<stdio.h>
#include<string.h>
void main{
int i,j;
char*a="#include<stdio.h>\n#include<string.h>\nvoid main{\n int i,j;\n char*a=%s%s%s;\n char b[1100];\n char*k=%s%s%s%s;\n char*s=%s%s%s%s;\n for(i=0,j=0;i<strlen(a);i++){\n switch(a[i]){\n case '%sn':\n b[j]='%s%s';\n b[j+1]='n';\n j+=2;\n break;\n case '%s%s':\n b[j]='%s%s';\n b[j+1]='%s%s';\n j+=2;\n break;\n case '%s%s':\n b[j]='%s%s';\n b[j+1]='%s%s';\n j+=2;\n break;\n default:\n b[j]=a[i];\n j++;\n }\n }\n b[j]='%s0';\n printf(a,k,b,k,k,s,k,k,k,s,s,k,s,s,s,s,k,s,s,s,k,s,s,s,s,s,s,s);\n}";
char b[1100];
char*k="\"";
char*s="\\";
for(i=0,j=0;i<strlen(a);i++){
switch(a[i]){
case '\n':
b[j]='\\';
b[j+1]='n';
j+=2;
break;
case '\"':
b[j]='\\';
b[j+1]='\"';
j+=2;
break;
case '\\':
b[j]='\\';
b[j+1]='\\';
j+=2;
break;
default:
b[j]=a[i];
j++;
}
}
b[j]='\0';
printf(a,k,b,k,k,s,k,k,k,s,s,k,s,s,s,s,k,s,s,s,k,s,s,s,s,s,s,s);
}

bleyman

Люди! Не используйте тег code никогда! Он не враппит строчки!
Используйте тег quote!
Так вот: суть единственного известного мне подхода к написанию подобных прог такова:
Есть текст проги. В виде строки. Он разбит на две половины: до иницализации строковой
переменной, и после. Самой инициализации нет.
Выводится первая половина, потом выводится весь текст, потом вторая половина.
Единственная сложность состоит в том, чтобы добиться корректного вывода ограничителей строки -
т.е. при выводе двух половин служебная запись ограничителя строки должна превращаться в
ограничитель строки, а при выводе инициализатора строковой константы она должна выводиться
"как есть" - т.е. в виде служебной записи. Это можно делать по разному.
А какие другие похожие проблемки бывают?

oleg_mcp

Есть еще программы полиглоты, которые компилируются сразу на нескольких языках. Видел одну аж на 5 сильно непохожих типа С, Perl, shell и т.п. Есть и полиглоты выводящие сами себя. На С + Lisp, например.
Среди программ Obfuscated C Contest есть программы, где можно поменять любые две строчки местами и программа все равно будет воспроизводить себя (или с точностью до перестановки строк, не помню).

Ivan8209

> Люди! <...> Он не враппит строчки!
Пра-ально!
Используйте auto-fill-mode.
---
"Vyroba umelych lidi, slecno, je tovarni tajemstvi."
Karel Capek

Elina74

Ага... Если враппить строчки, то получится фигня, а не программа. В моей проге так быть не должно...
Оставить комментарий
Имя или ник:
Комментарий: