Перейти к публикации
Дедовский городской форум
RaD

конкурс: самая короткая программа на С - аналог Seq

Рекомендованные сообщения

Вот жутко старая задача. Написать программу, которая печатает свой собственный текст.

Язык не оговаривается. Файл исходник с диска не читать. ( и т.п. тоже не катит - память, например, читать).

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
если я не ошибаюсь, является одной из трех задач без которых язык не может называться языком программирования..

 

Может быть. Вспомнил книгу в которой она мне встретилась.

Чарльз Уэзерелл, Этюды для программистов, 1982 (год русского издания)

Не знаю кто автор задачи, но скорее всего он.

Суть проблемы. Допустим синтаксис языка достаточно прост и позволяет печатать оператором

print ТЕКСТ_НА_ПЕЧАТЬ.

Поскольку собираемся печатать свой собственный исходник, то придется как минимум использовать кострукцию

print print

после этого имеем один print в распечатке и два в программе, вот такая засада.

Помнится севый вариант печатал все от первого #include <stdio.h> до последней закрывающей фигурной скобки.

Но как это было проделано я не помню :)

 

Charles Wetherell. "Etudes for programmers". Prentice Hall. 1978.

 

значит ей как минимум 30 лет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

/*

Еще там был очередной пример программы, печатающей свой же собственный текст. А вы разберетесь, как она это делает? :))

*/

 

class C

 

{

 

const string s = @"

 

class C

 

{{

 

const string s = @{1}{0}{1};

 

static void Main()

 

{{

 

System.Console.WriteLine(s,s,'\u0023');

 

System.Console.ReadLine();

 

}}

 

}}";

 

static void Main()

 

{

 

System.Console.WriteLine(s,s,'\u0023');

 

System.Console.ReadLine();

 

}

 

}

 

 

/*

Желающие также могут поразмыслить над тем, как работает GC, а также проверить в курсе ли они подводных различий .NET FW 1.1 и 2.0. Смотрите другие задачки тут:

 

http://msdn.microsoft.com/vcsharp/

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Еще там был очередной пример программы, печатающей свой же собственный текст. А вы разберетесь, как она это делает? :))

интересный пример, но если присмотреться внимательно то можно увидеть несколько вещей:

 

1. сточка const string s = @" // у неё всего лишь одна ковычка и нет точки с запятой(в C# много чего должно кончаться ;) => либо это ошибка, либо хитрость, потом стоит знак @ это значит что печатать всё что находиться между ковычками...немного посмотрев на код мы находим ковычку - }}"; и точку с запятой... а между двумя ближайшими ковычками стоит небольшой кусок кода, который и должен выводиться...

 

2. потом идёт стандартная строка вызова главной функции - static void Main() и пока я не совсем врубил в перегруженный вызов функции System.Console.WriteLine();, но это не так важно ))

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

только ошибка в коде :)

 

должно быть \u0022 - символ кавычки двойной, а в приведенном коде \u0023 - #

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Всегда найдется тот, кто не верит в то, что земля крутиться вокруг солнца:)

0023 - это двадцать три, а не тридцать пять, как Вы утверждаете( перед 16-тиричным представлением числа пишется 0x во всех си-подобных языках). Это код не код кавычки и уж тем более не решетки(см _ttp://www.asciitable.com/).

 

Kevin, как это неважно? В WriteLine вся фишка...

 

Ещё одна нетривиальная задачка ставящая си-подобные языки на место плевательницы:

int i=5;
i++=++i+i++;// чему равно i в c,c++,c#?

развернутый ответ приветствуется:)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

#include <stdio.h>

int main () {

int i=5;

i=++i+i++;

printf("%d",i);

return 0;

}

 

 

i=++i+i++;

последовательность разбора этого выражения

1)++i == 6

2) 6+ i++ == 12

3) i= 12

4) срабатывает постинкремент от i++. в итоге i==13;

 

PS: тут фишка в приоритетах между i++ и присваиванием в разных языках. может получиться и 12.

Не надо писать глупый код, тогда и плеваться не пригодится.

Изменено пользователем Kozdik

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

ну, насчёт инкрементов, то это конеш боян...

 

тут важно понимать отличие преинкремента ++i от постинкремента i++.

в первом случае сначало увеличить на 1, затем возвратить значение...

во втором же сначало возвратить значение, а затем увеличить...

 

 

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

то есть если

 

#include <iostream>

 

using namespace std;

int main()

{

int i=5;

int b;

 

b=++i;

cout << "b=" << b;

cout << endl;

cout << "i=" << i;

cin >> b;

}

 

это выведет:

b=6;

i=6;

 

 

 

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

а если

 

using namespace std;

int main()

{

int i=5;

int b;

 

b=i++;

cout << "b=" << b;

cout << endl;

cout << "i=" << i;

cin >> b;

}

 

это выведет:

b=5;

i=6;

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Kozdik, ваши рассуждения идут в разрез с моим вопросом(i++=++i+i++), приоритет ++ постпрефиксный и префиксный в с,с++,с# выше приоритета присваивания(=), последовательность рассуждений непонятна, оператор присваивания(=) это не проверка на истину(==) ;)

 

Kevin, это не ответ это выжимка из лекции походу:)

 

подсказка, приведеный код даст разные результаты на компиляторе gcc / MSVS:) потому что в стандарте нет четкого описания как действовать в данном случае.

 

вот тоже боян:

for(;P("\n"),R--;P("|"))for(e=C;e--;P("_"+(*u++/%2))P("| "+(*u/4)%2);

Данный кусок с лексической и синтактической стороны абсолютно верный в си с плюсами.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Kozdik, ваши рассуждения идут в разрез с моим вопросом(i++=++i+i++), приоритет ++ постпрефиксный и префиксный в с,с++,с# выше приоритета присваивания(=), последовательность рассуждений непонятна, оператор присваивания(=) это не проверка на истину(==) ;)

А ты уверен, что в качестве леводопустимого выражения может стоять операция инкремент?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

опечатался(праздники-то не кончались ещё;), естественно там аккумулирование стоит:

i+=++i+i++;

 

:)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
опечатался(праздники-то не кончались ещё;), естественно там аккумулирование стоит:

i+=++i+i++;

 

:)

ну тогда как все уже догадались ответ равен 19... ну это же просто... логика? зачем здесь логика? у меня сейчас нет трафика, но попозже я представлю вам (надеюсь) почему так происходит. здесь все дело в ОПН (обратной польской записи) при разборе получается всего лишь 1 лишний инкремент... ничего сложного

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

подсказка, приведеный код даст разные результаты на компиляторе gcc / MSVS:) потому что в стандарте нет четкого описания как действовать в данном случае.

 

и обратная польская запись тут не причем:

 

"At certain specified points in the execution sequence called sequence points, all side effects of previous evaluations shall be complete and no side effects of subsequent evaluations shall have taken place"

5. Expressions

4) Except where noted, the order of evaluation of operands of individual operators and subexpressions of individual expressions, and the order in which side effects take place, is unspecified. Between the previ- ous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression. Fur- thermore, the prior value shall be accessed only to determine the value to be stored. The requirements of this paragraph shall be met for each allowable ordering of the subexpressions of a full expres- sion; otherwise the behavior is undefined.

 

студия(монопрожекта нет под рукой и ответ там будет другой) сишарп:

post-638-1231079540.jpg

Изменено пользователем Maksim

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
приведеный код даст разные результаты на компиляторе gcc / MSVS[/b]

странно, у меня в борланде хоть на С хоть на С++ выдает один и тот же результат, а если один компилятор выдает разные результаты при компилировании одной и той же программы значит он уёб... плохой

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Кто-то хреново читает посты...

 

В тексте на англицком порусски сказано что имеет место быть undefined behaviour(неопределенно!!!), отсюда как создатель компилятора захочет поступить в данной ситуации- так и поступит.

ПС:

 

gcc - это один компилятор(ответ будет один)

MSVS - это компилятор из студии майкрософт(ответ будет другой)

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

 

и компилятор языка C от борланда это версии 1.0 что ли? ОМГ.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Maksim, тебе делать некуй?

 

насколько я понимаю - искусство программирования сделать программу максимально быстрой а код наиболее понятным, а не так чтобы над каждой строчкой иметь моск себе.

Изменено пользователем KeViN

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Всегда найдется тот, кто не верит в то, что земля крутиться вокруг солнца:)

это не вопрос веры

символы юникода \uxxxx в шарпе задаются в 16 ричном виде.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

balmaster, опачки и вправду: _ttp://msdn.microsoft.com/en-us/library/aa664812(VS.71).aspx буду знать:)

но исходник всёравно верный и сам себя печатает... что теперь в моем понимании оного - странно.

 

Kevin понятный код и максимальная быстрота - несовместимы, так что понимания нет, а хамство у тебя - есть :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

×
×
  • Создать...