LINUX.ORG.RU

if else ненужно

 ,


0

3

a(){printf("Yes\n");}
b(){printf("No\n");}

ex(a){
	((void(*)())a)();
}
f(u,l,r){
	ex(u*(l-r)+r);
}

main(){
	f(1<2,a,b);
}

Наряду с ненужностью goto в Сях не нужно if.

затруднения(не охота на прямую адресса возврата писать) в реализации break из концевой рекурсии как замены цыкла . чё подскажите?

★★☆

Последнее исправление: qulinxao (всего исправлений: 1)

Ответ на: комментарий от Harald

а, все, понял, вызов функции по указателю

Harald ★★★★★
()

можно выкинуть вообще почти все операторы, но брейнфак уже изобрели же

anonymous
()

чё подскажите?

закусить.

archimag ★★★
()
Ответ на: комментарий от lazyklimm

[psil] сахар же [/psil]

и тадыть уж отложено ((char(*))(1<2?a:b))()

не удобно что унарные как слева так и справа приходится скопками флеймить

qulinxao ★★☆
() автор топика

тогда не останется смысла использовать C - оптимизация коту под хвост

vaino
()

tail recursion на с.

#include <stdio.h>

int f_(int a, int i)
{
l1:
	if (i > 0) {
		a *= i--;
		goto l1;
	} else {
		return a;
	}
}

int f(int i)
{
	return f_(1, i);
}

int main()
{
	printf("%d\n", f(5));
	return 0;
}
Но главный вопрос: зачем?

nanoolinux ★★★★
()

подписался на Гуру-тред

x0r ★★★★★
()
Ответ на: комментарий от anonymous

нет по 4 словам из 7 слов вопроса.

qulinxao ★★☆
() автор топика
Ответ на: комментарий от nanoolinux

Правда штоли? буду знать.

вместо готу - добавили while/for/do_while/switch - вместо итераций предложили чтоб компайлер/интерпретатор заменыл бы вызов себя с последующим выходом из текущей копии на переход на начала текущей копии с изменёными аргументами

отсюда вопрос :

как бы в хвостовой рекурсии заменяющей вечный цикл вписать нечто что по функции break - при вышеуказаной реализации выбора.

qulinxao ★★☆
() автор топика
Ответ на: комментарий от anonymous

отчего овно?

((type)(*)name)(arrgs...) - некоторе бендинг мозги

жаль конечно что нельзя так это же : уменшив число скобок на что то вроде

cast( type(*)(),name)(args...)

qulinxao ★★☆
() автор топика
Ответ на: комментарий от aedeph_

не не не какая самая короткая реализация lisp repl на с . с последующим независимым исполнением (т.е что бы репл мог делать имэйджи и на следующей итерации весь бинарь это лисп код прошедший через начальный репл)

qulinxao ★★☆
() автор топика
Ответ на: комментарий от tailgunner

ты уже 3 раз - стабильност признак мастерства.

qulinxao ★★☆
() автор топика
Ответ на: комментарий от qulinxao

А ты лишь ответил всего 2 - пока подмастерье.

anonymous
()
Ответ на: комментарий от qulinxao

отчего овно?

Ну проверь: не плюсанут - значит нормальный код (ну или уныло).

anonymous
()

Да по тебе ФСНК плачет. Давно на крокодила-то подсел?

redgremlin ★★★★★
()

чё подскажите?

А ну-ка, заплили-ка аналог такого кода:

#include <stdio.h>

main() {

int i=42;

if (1<2) i++; i--;

printf("%d\n",i);

}

no-such-file ★★★★★
()
Ответ на: комментарий от aptyp

Тем не менее условие < остаётся же.

Это не условие, а оператор, такой же, как + или -. В крайнем случае можно обойтись вычитанием и побитовыми операциями.

anonymous
()

Конечно, я всегда вместо if-else пишу (expr) ? {} : {} даже в многострочных конструкциях. Более лаконично.

Deleted
()
Ответ на: комментарий от Deleted

многострочные конструкции? не незнаю.

код должен помещатся в 23 строки что бы ветки не висели - так что рефакторить рефакторить рефакторить.

qulinxao ★★☆
() автор топика
Ответ на: комментарий от no-such-file
#include <stdio.h>
#include <stdbool.h>

typedef void* poly;

poly if_(bool p, poly x, poly x_scp, poly y, poly y_scp)
{
    return ((poly(*)())(p * (x - y) + y))(p * (x_scp - y_scp) + y_scp);
}

int inc(int *x) { return ++*x; }
int dec(int *x) { return --*x; }

int main(void)
{
    int r, i = 42;

    r = (int) if_(1 < 2, inc, &i, dec, &i);

    printf("r = %d, i = %d\n", r, i);

    return 0;
}
$ clang -Wall -Werror foo.c -o foo
$ ./foo
r = 43, i = 43

gcc более привередлив (cast from pointer to integer of different size).

quasimoto ★★★★
()
Ответ на: комментарий от aptyp

точнее


       IFF(ls(a,b), .....)

где

ls(a,b){ return max(b-a,0);}
max(a,b){   return (a+b+abs(a-b))>>1;}

qulinxao ★★☆
() автор топика
Ответ на: комментарий от dave

замыкания к классическому( where sizeof(pointer)==sizeof(memory cell)==sizeof(int)) C прикручиваются вполне быстро. контексты явно передаются ну и свои malloc и без явного free - ведь как известно в С нет динамической памяти.

qulinxao ★★☆
() автор топика

затруднения(не охота на прямую адресса возврата писать) в реализации break из концевой рекурсии как замены цыкла . чё подскажите?

а придется :)

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

или адрес возврата вычислять на первом уровне вложенности и передавать его потом дальше аргументом. Как-то так:

#define tailrecf(n) tailrecf_(n, 1, 1, 0)

int tailrecfn_(int n, int i, int result,  int *ret_addr)
{
int *r[1];

  if (!ret_addr)
  {
  return tailrecfn(n, 1, 1, r[2]);//смещение подбирать в зависимости от архитектуры проца и опций компилятора
  }
  
 if (i == n)
  {
  r[2] == ret_addr;
  return result;
  }

i++;

return tailrecfn_(n, i, result * i, ret_addr);
}

Harald ★★★★★
()
Ответ на: комментарий от quasimoto
#include <stdbool.h>

typedef void* poly;
typedef char* addr;

poly if_(bool p, poly x, poly x_scp, poly y, poly y_scp);

poly if_(bool p, poly x, poly x_scp, poly y, poly y_scp)
{
    return ((poly(*)())(p * ((addr)x - (addr)y) + (addr)y))
        (p * ((addr)x_scp - (addr)y_scp) + (addr)y_scp);
}
$ clang --std=c89 -Weverything -Werror -c foo.c                                1 ↵
foo.c:11:13: error: cast from 'addr' (aka 'char *') to 'poly (*)()' increases
      required alignment from 1 to 4 [-Werror,-Wcast-align]
    return ((poly(*)())(p * ((addr)x - (addr)y) + (addr)y))
            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
$ gcc --std=c89 -pedantic -W -Werror -c foo.c                                  1 ↵
cc1: warnings being treated as errors
foo.c: In function ‘if_’:
foo.c:11:13: error: ISO C forbids conversion of object pointer to function pointer type
quasimoto ★★★★
()

тебе нужен forth

anonymous
()
Ответ на: комментарий от qulinxao

замыкания к классическому( where sizeof(pointer)==sizeof(memory cell)==sizeof(int)) C прикручиваются вполне быстро

Значит на Linux/x86_64 не «классический» С, потому что sizeof(void*) != sizeof(int).

свои malloc и без явного free

GC? Конечно, можно написать рантайм языка с ФВП и замыканиями на си. Но это не «вполне быстро» и не вполне удобно в использовании (почему придумали Vala вместо того чтобы писать на голом си + glib, другое дело, что glib как рантайм довольно слабенький).

ведь как известно в С нет динамической памяти

malloc, free, calloc и realloc - часть стандарта С. А вот тот твой код из ОП ему не соответствует.

quasimoto ★★★★
()

Оптимизация tail recursion делается кроссплатформенно с помощью trampoline.

rand
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.