2010-02-03 24 views
16

Questo mi è stato chiesto in un'intervista! ho davvero avuto confusoarray di N puntatori a funzioni che restituiscono puntatori alle funzioni

  • Come faccio a dichiarare un array di N puntatori a funzioni che ritornano puntatori a funzioni di tornare puntatori a caratteri

potrebbe qualcuno si prega di aiuto?

+3

che domanda stupida di intervista. C'è una ragione per Internet. È così che possiamo cercare sintassi arcane quando è necessario e non dover ingombrare il nostro cervello con esso. –

+8

'apt-get install cdecl; echo dichiara una matrice di puntatore alla funzione che restituisce il puntatore alla funzione restituisce il puntatore a char | cdecl; '>>>' char * (* (* var [])())() ' –

+1

@Doug T: Sembra ragionevole per me. Saper affrontare le dichiarazioni complicate è, sfortunatamente, un'abilità molto utile in C. –

risposta

33

I typedef sono per i wusses. Ecco un metodo meccanico semplice per capire le dichiarazioni pelose:

  a     -- a 
      a[N]    -- is an N-element array 
     *a[N]    -- of pointers 
     (*a[N])()   -- to functions 
     *(*a[N])()   -- returning pointers 
     (*(*a[N])())()  -- to functions 
    *(*(*a[N])())()  -- returning pointers 
char *(*(*a[N])())()  -- to char. 

Quindi, la risposta è nel quartiere di char *(*(*a[N])())();. Dico "nel vicinato" poiché non viene mai specificato quali argomenti le funzioni assumono.

È una domanda di intervista sgradevole (tipi questo brutto sono IME veramente rari), ma dà all'intervistatore un'idea di quanto bene comprendi i dichiaratori. O quello o erano annoiati e volevano solo vedere se potevano farti chiudere il cervello.

EDIT

La maggior parte di tutti gli altri consiglia di utilizzare typedef. L'unica volta che raccomando di usare typedef è se il tipo deve essere veramente opaco (cioè non manipolato direttamente dal programmatore, ma passato a un'API, un po 'come il tipo FILE). Altrimenti, se il programmatore ha lo scopo di manipolare direttamente oggetti di quel tipo, allora IME è meglio avere tutte quelle informazioni disponibili nella dichiarazione, per quanto brutto possa essere. Ad esempio, qualcosa come

NameFuncPickerPointer a[N]; 

mi dà alcuna informazione su come effettivamente usoa[i]. Non so che lo a[i] sia richiamabile, o che cosa restituisca, o quali argomenti dovrebbe prendere (se ce ne sono), o molto altro. Devo andare a cercare il typedef

typedef char *NameFunc(); 
typedef NameFunc *NameFuncPicker(); 
typedef NameFuncPicker *NameFuncPickerPointer; 

e da quel puzzle come scrivere l'espressione che in realtà chiama una delle funzioni.Mentre utilizzando la, dichiarazione di non-typedef "nudo", so subito che la struttura della chiamata è

char *theName = (*(*a[i])())(); 
+0

Ora questo ** I ** capisce anche senza essere un programmatore c. –

+1

Per quanto riguarda i nomi, credo che mi piacerebbe vedere 'StringGetter_Getter a [N]', o 'StringGetter_Getter_Array a', o 'FunctionTable a'. Deve avere un significato nel contesto del codice, e preferisco vedere 'StringGetter_Getter' ripetuto dappertutto, che' char * (* (*)())() '. Ma questo potrebbe facilmente deviare nello stesso argomento se nominare le costanti: "Non voglio andare a cercare il valore di DEFAULT_HTTP_PORT, se qualcuno sta usando 80, voglio vedere 80 nella fonte". Come programmatori, l'indirezione è la causa e la soluzione di tutti i nostri problemi. –

+0

... e in definitiva, se il tuo codice C ha tabelle di funzioni di fabbrica che restituiscono funzioni di fabbrica, allora probabilmente hai fatto una svolta sbagliata sulla tua strada verso la classe "Painfully Complex Enterprise Java" ;-) –

6
typedef char* (* tCharRetFunc)(); 
typedef tCharRetFunc (* tFuncRetCharFunc)(); 

tFuncRetCharFunc arr[N]; 
+0

Penso che la domanda sia progettata per vedere se l'intervistato capisce typedef e fornisce una soluzione chiara-umana come questa o una soluzione tecnico-cattiva come quelle date in altre risposte. Come tale è una domanda abbastanza buona come queste cose vanno. – Elemental

3

Divide grosso problema in parti più piccole:

/* char_func_ptr is pointer to function returning pointer to char */ 
typedef char* (*char_func_ptr)(); 

/* func_func_ptr is a pointer to function returning above type */ 
typedef char_func_ptr (*func_func_ptr)(); 

/* the_array is array of desired function pointers */ 
func_func_ptr the_array[42]; 
0

E 'questo quello che stai cercando:

typedef char* charptr; 
typedef charptr (*innerfun)(); 
typedef innerfun (*outerfun)(); 

const size_t N = 10; 
outerfun my_outerfun_array[N]; 

spero mi sono corretto, sembra una domanda strana per me specialmente in un'intervista :(

0

L'uso di typedef come dice Christopher è davvero il solo modo umano di dichiarare una cosa del genere. t tyedefs, sarà diventato:

char *(*(*arr[10])(void))(void); 

(sì, ho dovuto barare e corse cdecl> dichiarare arr come serie 10 di puntatore a funzione (void) puntatore tornare alla funzione (void) tornando puntatore a char)

1

array di N puntatori a funzioni che ritornano puntatori a funzioni restituisce un char:

int (*(*arr_fp[n])(void))(void) 
Problemi correlati