- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
#include <stdio.h>
#include <stdlib.h>
void push(unsigned int a, unsigned int **stackpp)
{
**stackpp = a;
(*stackpp)++;
}
unsigned int pop(unsigned int **stackpp)
{
(*stackpp)--;
return **stackpp;
}
unsigned int fib(unsigned int a)
{
unsigned int stack[10000] = {0};
unsigned int *stackp = stack;
// локальные дефайны
#define PUSH(x) push(x, &stackp)
#define POP() pop(&stackp)
relative_label:
PUSH( (int)(&&result - &&relative_label ) );
PUSH(a);
goto shit;
result:
return POP();
shit:
while(stackp != stack)
{
unsigned int tmp = POP();
//printf("tmp = %u\n", tmp); отладочная перчать
fflush(stdout);
if (tmp == 0)
{
int _ret = POP();
PUSH(0);
goto *(&&relative_label + _ret);
}
else if (tmp == 1)
{
int _ret = POP();
PUSH(1);
goto *(&&relative_label + _ret);
}
else
{
PUSH(tmp-2); // предварительно сохраняем
PUSH( (int)(&&after_p1 - &&relative_label) );
PUSH(tmp-1);
continue;
after_p1: ;
unsigned int tmp1 = POP(); // возвращенное значение
unsigned int tmp2 = POP(); // предварительно сохраненное
PUSH(tmp1);
PUSH( (int)(&&after_p2 - &&relative_label) );
PUSH(tmp2);
continue;
after_p2: ;
unsigned int val = POP()+POP();
int _ret = POP();
PUSH(val);
goto *(&&relative_label + _ret);
}
}
// ERROR - стек размотался. Такого быть не должно
exit(-1);
// убираем локальные дефайны
#undef PUSH
#undef POP
}
int main(void)
{
for(unsigned int i = 0; i < 30; i++)
{
printf("%u ", fib(i));
}
return 0;
}
Этим кодом я доказывал одному типу какой-то бред, связанный с рекурсией. Типа он считал что ее нельзя реализовать через сраные циклы со стеком(или может просто хотел посмотреть на такую реализацию).
Надо короче сделать локальный #define чтобы он автоматически #undef при выходе из области видимости фукнции.
Dummy00001 13.01.2016 11:41 # +1
народ очень быстро забывает мат. часть. в русском к слову это проще: рекуррентная функция vs. рекурсивная функция. в англиском и то и другое называется рекурсией, а в русском первое ссылается на определение функции (фиб определена рекуррентно), а второе ссылается на реализацию (фиб можно реализовать с/без рекурсии.)
PS доказательство можно строить проще: процессора (или абстрактно машина Тюринга) не умеют рекурсию. они могут ее реализовать, но рекурсится им просто нет куда: они есть "простые" конечные автоматы. что собственно ты выше и реализовал.
roman-kashitsyn 13.01.2016 11:51 # 0
Пруфы-то будут? См. recurrence equation / relation.
Dummy00001 13.01.2016 11:58 # −1
roman-kashitsyn 13.01.2016 12:55 # −1
Dummy00001 13.01.2016 13:05 # 0
но и на форумах (где я первый раз проблему видел), и знакомые от туда, толпы народа с понятием "recurrence" не встречались.
3_14dar 13.01.2016 20:46 # 0
bormand 13.01.2016 20:56 # 0
Abbath 14.01.2016 04:35 # +4
3_14dar 14.01.2016 05:04 # 0
bormand 14.01.2016 07:15 # −1
TarasB 13.01.2016 12:53 # +1
Dummy00001 13.01.2016 13:07 # 0
chtulhu 13.01.2016 13:28 # 0
директивы препроцессора обрабатываются еще до лексического анализа
dxd 13.01.2016 13:56 # 0
3_dar 13.01.2016 20:15 # −1
bormand 13.01.2016 20:23 # +4
d_fomenok 13.02.2016 19:42 # 0
jey-val-star 25.08.2021 04:25 # 0