2016-01-23 8 views
5

Ho una funzione che verifica una matrice e restituisce un indice di matrice se la sonda ha esito positivo.Modo corretto per restituire un codice di errore per la funzione che restituisce size_t

Nel mio codice ho reso ogni tipo riguardante un indice di array a type_t per chiarezza.

Qual è il modo preferito per mantenere tale chiarezza per questa funzione? Devo prendere un argomento puntatore a una variabile di errore e impostarlo?

inline size_t 
lin_search(const double *pxa, const double x, const size_t idxlow, const size_t idxhigh) 
{ 
    for (size_t i = idxlow; i < idxhigh; i++) 
    { 
     if (pxa[i] <= x && pxa[i+1] > x) 
      return i; 
    } 

    return -1; // If I change the return type to f.ex long int this works 
       // but I am no longer consistent 

} 

Poi ho potuto usarlo come

index = linsearch(parray, x, 0, n - 1); 
if (index == -1) 
    ... not found 
+0

È possibile passare le funzioni al (firmato) 'ssize_t', invece? –

+0

Non ho 'ssize_t'. Potresti restituire 'SIZE_MAX' per indicare un errore? –

+0

'ssize_t' non è standard C (è POSIX). C ha 'ptrdiff_t', però. Detto questo, '(size_t) -1' è (AFAIK) sempre definito come' SIZE_MAX'; si potrebbe forse usare '#define LIN_SEARCH_ERR ((size_t) -1)' o simile. –

risposta

4

Un altro modo senza "perdere" size_t (size_t è il tipo corretto per indici di matrice) è restituire il valore dell'indice nella puntatore e ritorno codice come booleana:

bool 
    lin_search(...., size_t *index) { 
     bool found = false; 

     for (size_t i = idxlow; i < idxhigh; i++) { 
      if (pxa[i] <= x && pxa[i+1] > x) { 
       found = true; 
       *index = i; 
       break; 
      } 
     } 

    return found; 
} 

e è possibile chiamare:

size_t index; 

if (lin_search(...., &index)) { 
    /* use 'index' */ 
} 

In questo modo, non dovete scendere a compromessi con l'utilizzo di qualcosa di diverso size_t e il tipo di ritorno della funzione, dice ancora se l'indice è stato trovato.

+0

Penso che questo mantenga le cose molto coerenti, grazie per i suggerimenti – luffe

+0

Un'altra domanda di stile breve che potrebbe non giustificare una nuova domanda: Nei miei prototipi aggiungo 'const' a ogni parametro che non intendo cambiare, anche per quei valori che 'C' passa per default ad un valore copiato (es.' int's) come questo 'fn (const double x)': è questa buona pratica? Grazie ancora – luffe

+0

@luffe È innocuo. Ma personalmente non penso che sia utile in ogni caso. Vedi: http://stackoverflow.com/questions/1724051/const-correctness-for-value-parameters e –

1

Situazioni come queste non sono inedite. Prendiamo ad esempio la definizione di fgetc, che legge i caratteri:

int fgetc(FILE *stream); 

fgetc() legge il carattere successivo dal flusso e lo restituisce come un cast unsigned char a int o EOF sulla fine del file o errore.

Questa funzione restituisce un valore che può essere fuso a unsigned char sul successo, e ritorno EOF (tipicamente -1) in caso di fallimento.

Un altro esempio è ftell, che riporta l'offset in un file corrente:

long ftell(FILE *stream); 

In caso di superamento, ... ftell() restituisce la corrente offset. Altrimenti, viene restituito -1 e errno è impostato per indicare l'errore .

Gli scostamenti di file sono sempre non negativi, pertanto restituire un valore negativo indica la modalità di segnalazione degli errori.

Quindi penso che la modifica del tipo di ritorno su long sia accettabile per un caso come questo.

Problemi correlati