Недавно передо мной встала нелёгкая задачка, которую мне подкинул один знакомый. Суть состоит в том, чтобы, написав один исходник, можно было его скомпилировать в gcc и исполнить, также и исполнить через интерпретатор perl. Казалось бы, не так уж и сложно, но не всем программистам придёт в голову, как правильно написать данный исходник. Приступим к рассмотрению изначальных программ на C и Perl. Голый Си: Code: #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { int sum=0; int i; for (i=1; i<argc; i++) sum+=atoi(argv[i]); printf("%d\n", sum); return 0; } Проверяем: Code: cyber@punk:/opt# gcc test.c -o test1 cyber@punk:/opt# ./test1 -2 15 -13 0 cyber@punk:/opt# ./test1 2 4 6 12 Теперь аналог на Perl: Code: #!/usr/bin/perl $sum=0; foreach (@ARGV) { $sum+=$_; } print "$sum\n"; Снова проверяем: Code: cyber@punk:/opt# perl test.pl 3 15 10 20 48 Теперь приступим решению поставленной задачи. Приведу сразу готовый исходник для рассмотрения: Code: #include <stdio.h> #include <stdlib.h> #define $ /* */ #define ARGV argv #define if($x) int main(int argc, char *argv[]) #define $start 1 #if PERL sub atoi { $_[0] } $ argc=@ARGV; $ start=0; $ x=1; #endif if($x) { int $ sum; int $ i; $ sum=0; for ( $ i = $start; $ i < $ argc ; $ i++) { $ sum += atoi ($ ARGV [$ i]);} printf("%d\n", $ sum); exit(0); } Тестируем результат: Code: cyber@punk:/opt# perl test4.c 3 15 10 20 48 cyber@punk:/opt# gcc test4.c -o test4 cyber@punk:/opt# ./test4 3 15 10 20 48 Давайте рассмотрим хитрости обоих языков, использованные при написании. Perl интерпретирует знак #, как начало комментария до конца строки, это дает возможность использовать директивы препроцессора Си, которые Perl будет игнорировать. Синтаксис языка Perl допускает пробел между знаком $ и именем переменной. Поэтому определение #define $ /* */ позволит в Си интерпретировать переменную вида $ var, как var, а в perl - как $var. В Си параметры командной строки передаются как char *argv[], а в perl - ARGV. Проблему решает директива: # define ARGV argv. В Си нулевой аргумент - это имя программы, а в Perl ARGV - переданный параметр. Обходится это введением переменной start, которая в Си устанавливается в единицу, а в Perl - в ноль. Кусок кода Perl экранируется в Си директивой #if PERL. Синтаксис операторов for и printf в Perl и Си одинаков, поэтому никаких дополнительных мер тут не требуется. На этом, в принципе, и все. Возможно у вас есть другие методы написания подобных "двуязычных" программ. С нетерпение жду ваших решений!
Интересная статья. Правда такая двуязычная программа может потребоваться только в каком то экзотическом случае. При написании кода нужно учитывать то, что пишем под два языка, поэтому нужно быть особенно внимательным, учитывать всевозможные нюансы.
Кибер панк как всегда на высоте))) с удовольствием прочитал статью) конечно такое часто не станешь применять только тогдав когда вообще выхода нету и путь лежит через извращения