программа-самовывод
Что тренирует создание таких программ?
ничего
ну -- максимум -- умение работать с динамической памятью и циклами %)
А зачем там динамическая память?
можно и без неё
можно и статическим массивом
просто я так привык
видел сайтик с подборкой таких прог на сотне языков, я думаю гугл поможет.
Они обычно представляют из себя массив строк программы + вывод этого массива на экран. Единственная сложность со строками - символы '"' нужно выводить по особому. В разных языках это решается по разному. В С/C++ можно вывести код этого символа.
я, когда баловался этим, обошелся 2-мя строковыми переменными..
а как?
разве что на си с использованием служебных символов...
и то хз
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.
2 строковые переменные - это массив из двух строк. Твоя программа по смыслу принадлежит именно к этому типу, а большие массивы возникают из-за того, что программы занимают несколько строчек для красоты и понятности. Были бы интересны другие возможные варианты.
а тогда какой аутпут у вот этого кода:
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
Видимо я просто недогоняю...
ну скомпиль да разберись!
#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);
}
Используйте тег quote!
Так вот: суть единственного известного мне подхода к написанию подобных прог такова:
Есть текст проги. В виде строки. Он разбит на две половины: до иницализации строковой
переменной, и после. Самой инициализации нет.
Выводится первая половина, потом выводится весь текст, потом вторая половина.
Единственная сложность состоит в том, чтобы добиться корректного вывода ограничителей строки -
т.е. при выводе двух половин служебная запись ограничителя строки должна превращаться в
ограничитель строки, а при выводе инициализатора строковой константы она должна выводиться
"как есть" - т.е. в виде служебной записи. Это можно делать по разному.
А какие другие похожие проблемки бывают?
Среди программ Obfuscated C Contest есть программы, где можно поменять любые две строчки местами и программа все равно будет воспроизводить себя (или с точностью до перестановки строк, не помню).
Пра-ально!
Используйте auto-fill-mode.
---
"Vyroba umelych lidi, slecno, je tovarni tajemstvi."
Karel Capek
Ага... Если враппить строчки, то получится фигня, а не программа. В моей проге так быть не должно...
Оставить комментарий
loks-po
Зачем нужна в народном хозяйстве программа-самовывод (хотя, может быть я неправильно называю ЭТО). Я часто встречал их примеры на различных форумах как изящное, но не очень применимое на практие явление. Что тренирует создание таких программ и вообще, как это возможно. Можно пример из паскаля? С++/С я не знаю, но прочитать программу смогу - т.ч. можно и на С...Заранее спасибо.