Meta-programación (III): Colección de quines en C

Siguiendo con los artículos anteriores sobre meta-programación y quines, os dejo una recopilación (extraída de varios sitios de quinéfilos como este ) de unos cuantos programas que generan su propio código en varios lenguajes de programación diferentes, para que veáis cómo se entretienen algunos hackers…

Quines en C

  • Autor: Desconocido (de The Jargon File)
  • Notas: Los primeros ejemplos son variaciones de quines de una línea en C estándar.
main(){char *c="main(){char *c=%c%s%c;printf(c,34,c,34);}";printf(c,34,c,34);}
  • Autor: Joe Miller
  • Notas: Provoca varios warnings, pero compila bien.
p="p=%c%s%c;main(){printf(p,34,p,34);}";main(){printf(p,34,p,34);}
  • Autor: John Burger, David Brill, Filip Machi
main(){char q=34,n=10,*a="main(){char q=34,n=10,*a=%c%s%c;printf(a,q,a,q,n);}%c";printf(a,q,a,q,n);}
  • Autor: Desconocido.
main(){char*a="main(){char*a=%c%s%c;int b='%c';printf(a,b,a,b,b);}";int b='"';printf(a,b,a,b,b);}
  • Autor: Dario Dariol
main(a,b){a="main(a,b){a=%c%s%c;b='%c';printf(a,b,a,b,b);}";b='"';printf(a,b,a,b,b);}
  • Autor: Dario Dariol
main(a){printf(a="main(a){printf(a=%c%s%c,34,a,34);}",34,a,34);}
  • Autor: Desconocido.
char *p="char *p=%c%s%c;main(){printf(p,34,p,34);}";main(){printf(p,34,p,34);}
  • Autor: Dario Dariol
main(a){a="main(a){a=%c%s%c;printf(a,34,a,34);}";printf(a,34,a,34);}
  • Autor: Desconocido.
char f[] = "char f[] =%c%c%s%c;%cmain() {printf(f,10,34,f,34,10,10);}%c";main() {printf(f,10,34,f,34,10,10);}
  • Autor: Thad Smith
  • Notas: El autor afirma que este quine cumple estrictamente el estándar ANSI.
#include<stdio.h>
main(){char*c="\\\"#include<stdio.h>%cmain(){char*c=%c%c%c%.102s%cn%c;printf(c+2,c[102],c[1],*c,*c,c,*c,c[1]);exit(0);}\n";printf(c+2,c[102],c[1],*c,*c,c,*c,c[1]);exit(0);}
  • Autor: Torben Mogensen
char *a="\\\"char *a=%c%.1s%.1s%.71s%.1sn%c;main(){printf(a+2,a[1],a,a,a,a,a[1]);}\n";main(){printf(a+2,a[1],a,a,a,a,a[1]);}
  • Autor: Joe Miller
#define T(a) main(){printf(a,#a);}
T("#define T(a) main(){printf(a,#a);}\nT(%s)")
  • Autor: Erkki Ruohtula (eru@tnso04.tele.nokia.fi)
#define n(v,w) v(#w"\nn("#v","#w")");}
n(main(){puts,#define n(v,w) v(#w"\nn("#v","#w")");})
  • Autor: Paul Hsieh
#define X(Y) main(){printf("#define X(Y) %s\nX(%s)\n",#Y,#Y);}
X(main(){printf("#define X(Y) %s\nX(%s)\n",#Y,#Y);})
  • Autor: James C Hu
#define q(k)main(){puts(#k"\nq("#k")");}
q(#define q(k)main(){puts(#k"\nq("#k")");})
  • Autor: James C Hu
#define q(k)main(){return!puts(#k"\nq("#k")");}
q(#define q(k)main(){return!puts(#k"\nq("#k")");})
  • Autor: Jeff Hollingsworth
#define Z(q)q,#q
main()printf(Z("#define Z(q)q,#q\nmain()printf(Z(%s));\n"));
  • Autor: Desconocido.
char *f="char *f=%c%s%c;%c#define Q '%c'%c#define N '%cn'%c#define B '%c%c'%c#include <stdio.h>%cvoid main(){printf(f,Q,f,Q,N,Q,N,B,N,B,B,N,N,N);}%c";
#define Q '"'
#define N '\n'
#define B '\\'
#include <stdio.h>
void main(){printf(f,Q,f,Q,N,Q,N,B,N,B,B,N,N,N);}
  • Autor: Desconocido.
char a[] = "int main(){ printf(b,34,a,34,10,34,b,34,10,10,a,10); }";
char b[] = "char a[] = %c%s%c;%cchar b[] = %c%s%c;%c%c%s%c";
int main(){ printf(b,34,a,34,10,34,b,34,10,10,a,10); }
  • Autor: Travis Emmit
char *s="rfns-.%€uwnsyk-'hmfw%/xBa'*xa'@as'1x.@|mnqj-/x.uwnsyk-'*h'1/x002:.@‚";
main() {
printf("char *s=\"%s\";\n",s);
while(*s)printf("%c",*s++-5);
}
  • Autor: Mark Wooding
#include <stdio.h>
int main(void){char n='\n';char b='\\';char q='"';char*p="#include <stdio.h>%cint main(void){char n='%cn';char b='%c%c';char q='%c';char*p=%c%s%c;printf(p,n,b,b,b,q,q,p,q,n);return 0;}%c";printf(p,n,b,b,b,q,q,p,q,n);return 0;}
  • Autor: Caucci Luca (caucci@cs.unibo.it)
/*
   Questo programma visualizza il suo codice sorgente.
   * Autore: Caucci Luca (e-mail: caucci@cs.unibo.it)
*/
#include <stdio.h>
char *s = "/*%c   Questo programma visualizza il suo codice sorgente.%c   * Autore: Caucci Luca (e-mail: caucci@cs.unibo.it)%c*/%c#include <stdio.h>%c%cchar *s = %c%s%c;%c%cvoid main() {%c   printf(s, 10, 10, 10, 10, 10, 10, 34, s, 34, 10, 10, 10, 10, 10, 10);%c   return;%c}%c";

void main() {
   printf(s, 10, 10, 10, 10, 10, 10, 34, s, 34, 10, 10, 10, 10, 10, 10);
   return;
}
  • Autor: Caucci Luca (caucci@cs.unibo.it)
/*
	Questo programma visualizza il suo codice sorgente.
	* Autore: Luca Caucci (e-mail: caucci@cs.unibo.it)
*/
#include <stdio.h>
char NewLine = '\n', Tab = '\t', BackSlash = '\\', QuotMark = '"';
char Str[] = "/*%c%cQuesto programma visualizza il suo codice sorgente.%c%c* Autore: Luca Caucci (e-mail: caucci@cs.unibo.it)%c*/%c%c#include <stdio.h>%c%cchar NewLine = '%cn', Tab = '%ct', BackSlash = '%c%c', QuotMark = '%c';%cchar Str[] = %c%s%c;%c%cint main() {%c%cprintf(Str, NewLine, Tab, NewLine, Tab, NewLine, NewLine, NewLine, NewLine, NewLine, BackSlash, BackSlash, BackSlash, BackSlash, QuotMark, NewLine, QuotMark, Str, QuotMark, NewLine, NewLine, NewLine, Tab, NewLine, Tab, NewLine, NewLine, NewLine);%c%creturn(0);%c}%c%c";
int main() {
	printf(Str, NewLine, Tab, NewLine, Tab, NewLine, NewLine, NewLine, NewLine, NewLine, BackSlash, BackSlash, BackSlash, BackSlash, QuotMark, NewLine, QuotMark, Str, QuotMark,  NewLine, NewLine, NewLine, Tab, NewLine, Tab, NewLine, NewLine, NewLine);
	return(0);
}
  • Autor: Daniel Martin
#include<stdio.h>
char a[] = "\";\nmain() {char *b=a;printf(\"#include<stdio.h>\\nchar a[] = \\\"\");\nfor(;*b;b++) {switch(*b){case '\\n': printf(\"\\\\n\"); break;\ncase '\\\\': case '\\\"': putchar('\\\\'); default: putchar(*b);}} printf(a);}\n";
main() {char *b=a;printf("#include<stdio.h>\nchar a[] = \"");
for(;*b;b++) {switch(*b){case '\n': printf("\\n"); break;
case '\\': case '\"': putchar('\\'); default: putchar(*b);}} printf(a);}
  • Autor: Jan Willem
#define s "#define s %c%s%c%c#include <stdio.h>%cvoid main() { printf(%c%s%c,34,s,34,10,10,34,s,34); }" #include <stdio.h>
void main() { printf("#define s %c%s%c%c#include <stdio.h>%cvoid main() { printf(%c%s%c,34,s,34,10,10,34,s,34); }",34,s,34,10,10,34,s,34); }
  • Autor: Desconocido.
void p(char *s){char *t;printf("%s(\"",s);for(t=s; *t!=0; t++)switch(*t){case '\\':case '\"':case'\'':putchar('\\');default:putchar(*t);}printf("\");}");}void main(){p("void p(char *s){char *t;printf(\"%s(\\\"\",s);for(t=s; *t!=0; t++)switch(*t){case \'\\\\\':case \'\\\"\':case\'\\\'\':putchar(\'\\\\\');default:putchar(*t);}printf(\"\\\");}\");}void main(){p");}
  • Autor: Michael Mauldin
char *x="\";\nmain ()\n{ char *s;\n printf (\"char *x=\\\"\");\n for(s=x;*s;s++)\n { printf
(*s=='\\\\'?\"\\\\\\\\\":*s=='\\\"'?\"\\\\\\\"\":*s=='\\n'?\"\\\\n\":\"%c\", *s); }\n printf (\"%s\", x);\n}\n";
main ()
{ char *s;
printf ("char *x=\"");
for(s=x;*s;s++)
{ printf (*s=='\\'?"\\\\":*s=='\"'?"\\\"":*s=='\n'?"\\n":"%c", *s); } printf ("%s", x);
}
  • Autor: Dave English <davide@sequent.com>
char x[]=" main() { int i; putchar(99); putchar(104); putchar(97); putchar(114); putchar(32);
putchar(120); putchar(91); putchar(93); putchar(61); putchar(34); for(i=0; i<strlen(x); ++i)
putchar(x[i]); putchar(34); putchar(59); for(i=0; i<strlen(x); ++i) putchar(x[i]); putchar(10); }";
main() { int i; putchar(99); putchar(104); putchar(97); putchar(114); putchar(32); putchar(120);
putchar(91); putchar(93); putchar(61); putchar(34); for(i=0; i<strlen(x); ++i) putchar(x[i]);
putchar(34); putchar(59); for(i=0 ; i<strlen(x); ++i) putchar(x[i]); putchar(10); }
  • Autor: Charles B Cranston (zben@ni.umd.edu)
main(){char*s="main(){char*s=%c%s%c;%cprintf(%c%s%c,34,s,34,10,34,s,34,10);}%c";
printf("main(){char*s=%c%s%c;%cprintf(%c%s%c,34,s,34,10,34,s,34,10);}%c",34,s,34,10,34,s,34,10);}
  • Autor: John Hagerman
#define p(s) printf("%s\n",s);
#define q(v,s) printf("r(%s,%s)\n",#v,s);
#define r(v,s) char*v=#s;
#define m main(){p(x)p(y)p(z)p(n)q(x,x)q(y,y)q(z,z)q(n,n)p("m")}
r(x,#define p(s) printf("%s\n",s);)
r(y,#define q(v,s) printf("r(%s,%s)\n",#v,s);)
r(z,#define r(v,s) char*v=#s;)
r(n,#define m main(){p(x)p(y)p(z)p(n)q(x,x)q(y,y)q(z,z)q(n,n)p("m")}) m
  • Autor: Xiao Zhiwei
#include
main()
{char* list="
printf(%c#include %cn%c);
printf(%cmain()%cn%c);
printf(%c{%c);
printf(%cchar* list=%cc%c,34);
printf(%c%cs%c, list);
printf(%c%cc;%c,34);
printf(list,34,92,34,34,92,34,34,34,34,37,34,34,37,34,34,37,34);}
";
printf("#include \n");
printf("main()\n");
printf("{");
printf("char* list=%c",34);
printf("%s", list);
printf("%c;",34);
printf(list,34,92,34,34,92,34,34,34,34,37,34,34,37,34,34,37,34);}
  • Autor: Dave Harif
#include <stdio.h>
#define d "\\"
#define c "\n"
#define b "\""
#define a "#include <stdio.h>%s#define d %s%s%s%s%s#define c %s%sn%s%s#define b %s%s%s%s%s#define a %s%s%s%smain(){printf(a,c,b,d,d,b,c,b,d,b,c,b,d,b,b,c,b,a,b,c,c);}%s"
main(){printf(a,c,b,d,d,b,c,b,d,b,c,b,d,b,b,c,b,a,b,c,c);}
  • Autor: Kennth Almquist
char*p="char*p=15415,4*x=52?33/n33/55,c,n,*q;main()33'0'&c<'6'?c<*x?n=69,'5':*(c-*x+x):c);return 0;33>4",   *x="2???/n??/"",c,n,*q;main()??'0'&c<'6'?c<*x?n=69,'"':*(c-*x+x):c);return 0;??>
  • Autor: Zefram (A.Main@dcs.warwick.ac.uk)
char *f="%c%s%c,";
#include <stdio.h>
char*x[]={
"char *f=%c%s%c;",
"#include <stdio.h>",
"char*x[]={",
"},z=0;main(){int n;",
"printf(*x,34,f,34);puts(&z);",
"puts(x[1]);puts(x[2]);",
"for(n=0;n<8;n++)printf(f,34,x[n],34),puts(&z);",
"for(n=3;n<8;n++)puts(x[n]);}",
},z=0;main(){int n;
printf(*x,34,f,34);puts(&z);
puts(x[1]);puts(x[2]);
for(n=0;n<8;n++)printf(f,34,x[n],34),puts(&z);
for(n=3;n<8;n++)puts(x[n]);}
  • Autor: John Burger, David Brill, Filip Machi
char *text [] = {
        "char *text [] = {",
        "0 };",
        "main () {",
        "        char newline = 012, quote = 042, escape = 0134, *p, **p;",
        "        printf (\"%s%c\", *text, newline);",
        "        for (pp = text; *pp; pp++) {",
        "                printf (\"        %c\", quote);",
        "                for (p = *pp; *p; p++) {",
        "                        if (*p == quote)",
        "                                putchar (escape);",
        "                        putchar (*p);",
        "                }",
        "                printf (\"%c,%c\", quote, newline);",
        "        }",
        "        for (pp = text + 1; *pp; pp++);",
        "}",
0 };
main () {
        char newline = 012, quote = 042, escape = 0134, *p, **pp;
        printf ("%s%c", *text, newline);

        for (pp = text; *pp; pp++) {
                printf ("        %c", quote);
                for (p = *pp; *p; p++) {
                        if (*p == quote)
                                putchar (escape);
                        putchar (*p);
                }
                printf ("%c,%c", quote, newline);
        }
        for (pp = text + 1; *pp; pp++)
                printf ("%s%c", *pp, newline);
  • Autor: Daniel Martin
#include<stdio.h>
char *a[] = {"\"};\n\n",
	"main() {\n",
	"  int i=0; char *b;\n",
	"  printf(\"#include<stdio.h>\\nchar *a[] = {\\\"\");\n",
	"  while(*a[i]) {\n",
	"    for(b=a[i];*b;b++)\n",
	"      switch(*b) {\n",
	"         case '\\n': printf(\"\\\\n\"); break;\n",
	"         case '\\\\': case '\\\"': putchar('\\\\'); \n",
	"         default: putchar(*b);\n",
	"      } \n",
	"    printf(\"\\\",\\n\\t\\\"\"); \n",
	"    i++;\n",
	"  }\n",
	"  i=0;\n",
	"  while(*a[i]) {printf(a[i]);i++;}\n",
	"}\n",
	""};

main() {
  int i=0; char *b;
  printf("#include<stdio.h>\nchar *a[] = {\"");
  while(*a[i]) {
    for(b=a[i];*b;b++)
      switch(*b) {
         case '\n': printf("\\n"); break;
         case '\\': case '\"': putchar('\\');
         default: putchar(*b);
      }
    printf("\",\n\t\"");
    i++;
  }
  i=0;
  while(*a[i]) {printf(a[i]);i++;}
}
  • Autor: Desconocido.
char s[] = "\";\n\
main ()\n\
{ int i; printf (\"char s[] = \\\"\");\n\
  for (i=0; s[i]; i++)\n\
  { switch (s[i]) {\n\
    case '\\n': printf (\"\\\\n\\\\\\n\"); break;\n\
    case '\\\\': printf (\"\\\\\\\\\"); break;\n\
    case '\\\"': printf (\"\\\\\\\"\"); break;\n\
    default:   printf (\"%c\", s[i]); break;}\n\
  }\n\
  printf (\"%s\",s); }\n\
";

main ()

{ int i; printf ("char s[] = \"");
  for (i=0; s[i]; i++)
  { switch (s[i]) {
    case '\n': printf ("\\n\\\n"); break;
    case '\\': printf ("\\\\"); break;
    case '\"': printf ("\\\""); break;
    default:   printf ("%c", s[i]); break;}
  }
  printf ("%s",s); }
  • Autor: pjs@euclid.jpl.nasa.gov (Peter Scott)
#include stdio

main()
{
int i;
char *a[27];
  a[0] = "#include stdio";
  a[1] = "";
  a[2] = "main()";
  a[3] = " {";
  a[4] = "   int i;";
  a[5] = "   char *a[27];";
  a[6] = "   for (i = 0; i <= 5; i++) printf (\"\%s\\n\", a[i]);";
  a[7] = "   for (i = 0; i <= 26; i++) printslash (\"   a[\%d] = \\\"\%s\\\";\\n\", i, a[i]);";
  a[8] = "   for (i = 6; i <= 26; i++) printf (\"\%s\\n\", a[i]);";
  a[9] = " }";
  a[10] = "";
  a[11] = "printslash (string, a1, a2)";
  a[12] = "char *string, *a2;";
  a[13] = "int a1;";
  a[14] = " {";
  a[15] = "   char b[100];";
  a[16] = "   int i;";
  a[17] = "   int j = 0;";
  a[18] = "   for (i = 0; i < strlen(a2); i++)";
  a[19] = "    {";
  a[20] = "      char ch = a2[i];";
  a[21] = "      if  b[j++] = '\\\\';";
  a[22] = "      b[j++] = ch;";
  a[23] = "    }";
  a[24] = "   b[j] = '\';";
  a[25] = " printf (string, a1, b);"; a[26] = " }";
  for (i = 0; i <= 5; i++) printf ("%s\n", a[i]);
  for (i = 0; i <= 26; i++) printslash ("   a[%d] = \"%s\";\n", i, a[i]);
  for (i = 6; i <= 26; i++) printf ("%s\n", a[i]);
}
printslash (string, a1, a2)
char *string, *a2;
int a1;
{
char b[100];
int i;
int j = 0;
for (i = 0; i < strlen(a2); i++)
{
      char ch = a2[i];
      if  b[j++] = '\\';
      b[j++] = ch;
}
b[j] = '';
printf (string, a1, b);
}
  • Autor: Celia La
#include <stdio.h>
char* a = ";

void main() {

char* c;

printf(\"#include <stdio.h>\\nchar* a = \");

putchar(34);
for (c = a; c[0] != 0; c++) {
if (c[0] == 34) { putchar(92); putchar(34); }
else if (c[0] == 92) { putchar(92); putchar(92); }
else putchar(c[0]);
}

putchar(34);
printf(\"%s\", a);}
";

void main() {

char* c;

printf("#include <stdio.h>\nchar* a = ");

putchar(34);
for (c = a; c[0] != 0; c++) {
if (c[0] == 34) { putchar(92); putchar(34); }
else if (c[0] == 92) { putchar(92); putchar(92); }
else putchar(c[0]);
}

putchar(34);

printf("%s", a);}
  • Autor: Joseph N. Wilson (jnw@cise.ufl.edu)
char *s= "char *s= \"%s\";\n\n/* Wilson's straightforward self-reproducing program */\n\nchar *q(char *s) {\n  char *r = (char *) malloc (strlen(s)*4 + 1);\n  int i, j = 0;\n\n  for (i=0; i < strlen(s); i) {\n    switch (s[i]) {\n      case '\\\\': r[j] = '\\\\'; r[j] = '\\\\'; break;\n      case '\\\"': r[j] = '\\\\'; r[j] = '\\\"'; break;\n      case '\\n': r[j] = '\\\\'; r[j] = 'n'; break;\n      default: r[j] = s[i]; break;\n      }\n    }\n  r[j++] = '\';\n  return r;\n}\n\nmain() {\n  printf(s, q(s));\n}\n";

/* Wilson's straightforward self-reproducing program */

char *q(char *s) {
   char *r = (char *) malloc (strlen(s)*4 + 1);
   int i, j = 0;
   for (i=0; i < strlen(s); i++) {
    switch (s[i]) {
     case '\\': r[j++] = '\\'; r[j++] = '\\'; break;
     case '\"': r[j++] = '\\'; r[j++] = '\"'; break;
     case '\n': r[j++] = '\\'; r[j++] = 'n'; break;
     default: r[j++] = s[i]; break;
     }
   }
 r[j++] = '';
 return r;
}

main() {
  printf(s, q(s));
}
  • Autor: Dan Hoey
  • Notas: Modificado ligeramente por Joe Miller. No solamente es un quine, es un palíndromo también,
/**/char q='"',*a="*//**/char q='%c',*a=%c%s%c*/};)b(stup;]d[b=]d-852
[b)--d(elihw;)q,a,q,q,2+a,b(ftnirps{)(niam;031=d tni;]952[b,",b[259];
int d=130;main(){sprintf(b,a+2,q,q,a,q);while(d--)b[258-d]=b[d];puts(
b);}/*c%s%c%=a*,'c%'=q rahc/**//*"=a*,'"'=q rahc/**/
  • Autor: Dan Hoey
  • Notas: Otro palíndromo.
/**/char q='"',*a="*//**/char q='%c',*a=%c%s%c*/};)b(stup;]d[b=]d-472[b)--d(elihw;)q,a,q,q,2+a,b(ftnirps;)b(stup{)(niam;731=d tni;]572[b,",b[275];int d=137;main(){puts(b);sprintf(b,a+2,q,q,a,q);while(d--)b[274-d]=b[d];puts(b);}/*c%s%c%=a*,'c%'=q rahc/**//*"=a*,'"'=q rahc/**/
  • Autor: Dan Hoey
  • Notas: Y otro palíndromo más.
/**/char
q='"',*a="*//**/char
q='%c',*a=%c%s%c*/};)]d-062[b=]d[b(rahctup)--d(elihw;)q,a,q,q,2+a,b(ftnirps{)(ni
am;162=d tni;]162[b,",b[261];int d=261;main(){sprintf(b,a+2,q,q,a,q);while(d--)p
utchar(b[d]=b[260-d]);}/*c%s%c%=a*,'c%'=q
rahc/**//*"=a*,'"'=q
rahc/**/
  • Autor: Dan hoey

Note: El último palíndromo…

/**/main(){char*a=/*/};)q,q,a,q,q,811+a(ftnirp;'"'=q,/**/"/**/main(){char*a=/*/};)q,q,a,q,q,811+a(ftnirp;'c%'=q,/**/c%s%c%/**/,q='c%';printf(a+118,q,q,a,q,q);}/*/=a*rahc{)(niam/**/main(){char*a=/*/};)q,q,a,q,q,811+a(ftnirp;'%c'=q,/**/%c%s%c/**/,q='%c';printf(a+118,q,q,a,q,q);}/*/=a*rahc{)(niam/**/"/**/,q='"';printf(a+118,q,q,a,q,q);}/*/=a*rahc{)(niam/**/
  • Autor: Dan Hoey
  • Notas: Se escribe a sí mismo de atrás hacia adelante.
main(){char*a="main(){char*a=c%s%c%,q='c%';printf(a+49,q,q,a,q);};)q,a,q,q,94+a(ftnirp;'%c'=q,%c%s%c=a*rahc{)(niam",q='"';printf(a+49,q,q,a,q);}
  • Autor: Dan Hoey
  • Notas: Otro que hace lo propio.
main(){char*a="main(){char*a=c%s%c%;printf(a+42,34,a,34);};)43,a,43,24+a(ftnirp;%c%s%c=a*rahc{)(niam";printf(a+42,34,a,34);}
  • Autor: smr
  • Notas: Este programa ganó el premio “Worst Abuse of the Rules” en el Campeonato de C ofuscado de 1994 Declara ser el programa en C más pequeño del mundo que escribe su propio código. ¡Además es un palíndromo!. Algunos compiladores dan errores fatales al compilarlo.

Bastante pequeño, ¿eh?

Hay muchos otros ejemplos más por la red, esta es solamente una pequeña parte de las grandes recolecciones de quines que se han programado, pero sirve para hacernos una idea de cuánto programador loco hay por el mundo 🙂

Un pensamiento en “Meta-programación (III): Colección de quines en C

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *