komplizierte Zeiger Funktionen

#1217070
Lesenswert?

Erstell doch mal einen Zeiger auf eine Funktion, welche einen Zeiger auf 
eine Funktion übernimmt (die meinetwegen einen int als Argument bekommt) 
und einen ebensolchen Zeiger zurückliefert. Und das alles machst du ohne 
typedef :-)

(Das wäre zb. eine Funktionszeiger auf eine Funktion die irgendwelche 
Handler registriert)

ohne Gewähr
1
void (*)(int) registerHandler( void (*arg)( int ) )
2
{
3
   ...
4
}
5

6
void foo( int arg )
7
{
8
}
9

10
int main()
11
{
12
  void (*)(int) (*RegisterFnct)( void (*)(int) );
13

14
  void (* OldFnct)(int);
15

16
  RegisterFnct = registerHandler;
17
  OldFnct = (*RegisterFnct)( foo );
18
}

Zum Drüberstreuen hätte ich jetzt gerne noch ein Array aus derartigen 
Funktionspointern und eine Funktion, die ein derartiges Array als 
Argument bekommt

(Machs nicht wirklich! Ohne typedef ist sowas hoffnungslos)
Gast #1217137
Lesenswert?

Ich habe vor vielen Jahren einen kleinen embeddable Compiler gebastelt,
der mathematische Funktionen mit mehreren Argumenten als Textstring
einliest und als 68000-Binärcode ausgibt, der wie eine normale
C-Funktion aufgerufen werden kann. Die Compilerfunktion sieht
vereinfacht etwa so aus:
1
double (*compiler(const char *source))(double *) {
2
  unsigned short *code;
3

4
  code = malloc(MAX_CODE_SIZE);
5
  // code generation
6
  // ...
7
  return (double (*)(double *))code;
8
}

Um im gleichen Programm unterschiedliche Compiler-Algorithmen
gegeneinander zu testen, könnte man ein Array mit Pointern auf die
einzelnen Compiler anlegen, so dass diese in einer Schleife der Reihe
nach durchgetestet werden können. Das Array sähe dann so aus:
1
double (*(*comp_array[])(const char *))(double *) = {
2
  compiler1, compiler2, compiler3
3
};

Typedefs fand ich damals noch uncool ;-)
Moderator (Firma: Titel) Persönliche Seite #1217146
Lesenswert?

Da reicht oft schon viel weniger aus:
1
char Zeichenkette[100];
2
char pZeichenkette;
3
:
4
  *pZeichenkette + irgendwo = irgendwas;
5
// oder
6
  *(char*)&Zeichenkette[0] + irgendwo = irgendwas;
7
// viele haben damit schon Probleme:
8
  Zeichenkette[irgendwo] = irgendwas; // Aufruf mit irgendwo==100   :-o
9
:
Persönliche Seite #1217242
Lesenswert?

1
extern int (*foo (int (*a (int))(int,int)))(int (*)(int,int));

Deklariert foo als eine Funktion mit einem Paramater a, welcher ein 
Zeiger auf eine Funktion ist, die 2 ints nimmt und einen 
Funktionspointer zurückliefert, die ihrerseits einen Funktionspointer 
auf eine Funktion liefert, die zwei ints nimmt und einen int 
zurückliefert.

In Mathe würd de man sagen foo ist ein Funktional .


Johann
#1217336
Lesenswert?

Der OP hat bereits im Titel des Threads das Stichwort geliefert:
kompliziert

Software ist nicht dazu da, um irgendetwas kompliziert auszudrücken. 
Software ist dazu da, um Sachverhalte logisch sauber und 
strukturiert darzustellen.

Das Programmieren ist der letzte - rein handwerkliche - Schritt bei der 
Software-Entwicklung.

Hier hat Kompliziertheit nichts aber auch garnichts zu suchen!

Bernhard
#1217359
Lesenswert?

Simon K. wrote:
> Bernhard R. wrote:
>> Kompliziertheit
> Komplexität?

Yep. Kompliziert ist immer relativ.

> Die Beispiele oben kann man ja durch typedefs vereinfachen,

Ich würd sogar sagen: Wenn jemand sowas ohne typedef macht, sollte man 
den Code ausdrucken und ihm den Ausdruck solange um die Ohren dreschen, 
bis er freiwillig auf Knien nach Lourdes pilgert, um Abbitte zu leisten 
:-)

> Jetzt mach dir mal nicht in die Hose.

lol
Gast #1217406
Lesenswert?

Folgendes hat scheinbar nichts mit Pointern zu tun. Bei näherem Hinsehen
ist es aber Pointer pur und stellt eine geniale Möglichkeit dar, zu tief
verschachtelte Klammern übersichtlicher darzustellen. Trotzdem würde ich
diesen Stil nicht zur Nachahmung empfehlen ;-)
1
#include <stdio.h>
2

3
int main(void) {
4
  static int a[8] = { 3, 7, 5, 2, 1, 6, 4, 0 };
5
  int i;
6

7
  for(i=0; i<8; i++)
8
    printf("%d\n", i[a][a][a][a][a][a][a][a]);
9
  return 0;
10
}
#1217414
Lesenswert?

Das Ganze beruht darauf, dass

    a[i]   dasselbe ist wie   i[a]

(folgt aus der C-Definition wie Array Indizierung über Pointer 
Arithmetik abgewickelt wird:
 Der Compiler formt a[i] sofort um zu *(a+i)   (*)
 und i[a] wird ohne Ansehen der Datentypen umgeformt zu *(i+a)

und so wie Pointer Arithmetik in C definiert ist, sind *(a+i) und *(i+a) 
identische Ausdrücke)

Der Ausdruck

     i[a][a][a][a][a][a][a][a]

ist äquivalent zu

     a[a[a[a[a[a[a[a[i]]]]]]]]

Bsp
 i sei gleich 1

a[1]           ist daher 7
a[a[1]]        ist daher gleich a[7]  oder 0
a[a[a[1]]]     ist daher gleich a[0]  oder 3
a[a[a[a[1]]]]                   a[3]  oder 2
.....
(Jetzt sollte das Prinzip schon klar sein. Der Index auf den zugegriffen 
wird, kommt selbst aus dem Array)


Eine Spielart davon, mit der man Leute verblüffen kann
1
 for( int i = 10; i >= 0; ++i )
2
   printf( "%c", i[ "Hallo World" ] );   // ein Integer wird mit einem String indiziert :-)

( ist aber dieselbe Idee.   a[i] <==> i[a] )

(*) Das ist auch der Grund, warum man beim Zugriff über Pointer auch 
Array Syntax benutzen kann. Eigentlich war das wahrscheinlich sogar die 
grundelegende Idee dahinter, dass man das können möchte
1
   char* a = malloc( 20 );
2
   a[0] = '\0';

geht deswegen, weil a[0] sofort umgeformt wird zu  *(a+0)  und da a ein 
Pointer ist, ist das jetzt eine legale Operation.
#1217439
Lesenswert?

Hallo,

hat jetzt zwar nicht nur mit Zeigern was zu tun, aber:
1
#include <stdio.h>
2

3
main(t,_,a)
4
char *a;
5
{return!0<t?t<3?main(-79,-13,a+main(-87,1-_,
6
main(-86, 0, a+1 )+a)):1,t<_?main(t+1, _, a ):3,main ( -94, -27+t, a
7
)&&t == 2?_<13?main ( 2, _+1, "%s %d %d\n" ):9:16:t<0?t<-72?main(_,
8
t,"@n'+,#'/*{}w+/w#cdnr/+,{}r/*de}+,/*{*+,/w{%+,/w#q#n+,/#{l,+,/n{n+\
9
,/+#n+,/#;#q#n+,/+k#;*+,/'r:'d*'3,}{w+K w'K:'+}e#';dq#'l q#'+d'K#!/\
10
+k#;q#'r}eKK#}w'r}eKK{nl]'/#;#q#n'){)#}w'){){nl]'/+#n';d}rw' i;# ){n\
11
l]!/n{n#'; r{#w'r nc{nl]'/#{l,+'K {rw' iK{;[{nl]'/w#q#\
12
n'wk nw' iwk{KK{nl]!/w{%'l##w#' i;:{nl]'/*{q#'ld;r'}{nlwb!/*de}'c \
13
;;{nl'-{}rw]'/+,}##'*}#nc,',#nw]'/+kd'+e}+;\
14
#'rdq#w! nr'/ ') }+}{rl#'{n' ')# }'+}##(!!/")
15
:t<-50?_==*a?putchar(a[31]):main(-65,_,a+1):main((*a == '/')+t,_,a\
16
+1 ):0<t?main ( 2, 2 , "%s"):*a=='/'||main(0,main(-61,*a, "!ek;dc \
17
i@bK'(q)-[w]*%n+r3#l,{}:\nuwloca-O;m.vpbks,fxntdCeghiry"),a+1);}

http://www.bernd-leitenberger.de/echte-programmierer.shtml
dort ganz nach unten scrollen.

Die monster.exe ist sauber, in der Dos-Box aufrufen, damit man die 
Ausgabe sieht. :-)

Gruß aus Berlin
Michael

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren