C Language
Jump Statements
Ricerca…
Sintassi
- return val; / * Restituisce dalla funzione corrente. val può essere un valore di qualsiasi tipo che viene convertito nel tipo di ritorno della funzione. * /
- ritorno; / * Restituisce dalla funzione void corrente. * /
- rompere; / * Salta incondizionatamente oltre la fine ("break out") di un'istruzione di iterazione (loop) o fuori dall'istruzione switch più interna. * /
- Continua; / * Salta incondizionatamente all'inizio di un'istruzione di iterazione (loop). * /
- goto LBL; / * Salta all'etichetta LBL. * /
- LBL: statement / * qualsiasi istruzione nella stessa funzione. * /
Osservazioni
Questi sono i salti che sono integrati in C per mezzo di parole chiave.
C ha anche un altro costrutto salto, salto in lungo, che è specificato con un tipo di dati, jmp_buf
, e chiamate alle librerie C, setjmp
e longjmp
.
Guarda anche
Usando goto per saltare fuori da loop annidati
Saltare fuori da cicli annidati di solito richiede l'uso di una variabile booleana con un controllo di questa variabile nei loop. Supponiamo che stiamo iterando su i
e j
, potrebbe assomigliare a questo
size_t i,j;
for (i = 0; i < myValue && !breakout_condition; ++i) {
for (j = 0; j < mySecondValue && !breakout_condition; ++j) {
... /* Do something, maybe modifying breakout_condition */
/* When breakout_condition == true the loops end */
}
}
Ma il linguaggio C offre la clausola goto
, che può essere utile in questo caso. Usandolo con un'etichetta dichiarata dopo i loop, possiamo facilmente uscire dai loop.
size_t i,j;
for (i = 0; i < myValue; ++i) {
for (j = 0; j < mySecondValue; ++j) {
...
if(breakout_condition)
goto final;
}
}
final:
Tuttavia, spesso quando si presenta questa necessità, è preferibile utilizzare un return
. Questo costrutto è anche considerato "non strutturato" nella teoria della programmazione strutturale.
Un'altra situazione in cui goto
potrebbe essere utile è passare a un gestore di errori:
ptr = malloc(N * x);
if(!ptr)
goto out_of_memory;
/* normal processing */
free(ptr);
return SUCCESS;
out_of_memory:
free(ptr); /* harmless, and necessary if we have further errors */
return FAILURE;
L'uso di goto
mantiene il flusso degli errori separato dal normale flusso di controllo del programma. Tuttavia è anche considerato "non strutturato" in senso tecnico.
Usando il ritorno
Restituzione di un valore
Un caso comunemente usato: ritorno da main()
#include <stdlib.h> /* for EXIT_xxx macros */
int main(int argc, char ** argv)
{
if (2 < argc)
{
return EXIT_FAILURE; /* The code expects one argument:
leave immediately skipping the rest of the function's code */
}
/* Do stuff. */
return EXIT_SUCCESS;
}
Note aggiuntive:
Per una funzione che ha un tipo restituito come
void
(non includendovoid *
o tipi correlati), l'istruzionereturn
non dovrebbe avere alcuna espressione associata; cioè, l'unica dichiarazione di reso ammessa sarebbe direturn;
.Per una funzione che ha un tipo di
void
nonvoid
, la dichiarazione direturn
non deve apparire senza un'espressione.Per
main()
(e solo permain()
), non è richiesta un'istruzionereturn
esplicita (in C99 o successive). Se l'esecuzione raggiunge il termine}
, viene restituito un valore implicito di0
. Alcune persone pensano che omettere questoreturn
sia una cattiva pratica; altri suggeriscono attivamente di lasciarlo fuori.
Non restituire nulla
Di ritorno da una funzione di void
void log(const char * message_to_log)
{
if (NULL == message_to_log)
{
return; /* Nothing to log, go home NOW, skip the logging. */
}
fprintf(stderr, "%s:%d %s\n", __FILE__, _LINE__, message_to_log);
return; /* Optional, as this function does not return a value. */
}
Usando la pausa e continua
continue
immediatamente a leggere su input non validi o break
la richiesta dell'utente o la fine del file:
#include <stdlib.h> /* for EXIT_xxx macros */
#include <stdio.h> /* for printf() and getchar() */
#include <ctype.h> /* for isdigit() */
void flush_input_stream(FILE * fp);
int main(void)
{
int sum = 0;
printf("Enter digits to be summed up or 0 to exit:\n");
do
{
int c = getchar();
if (EOF == c)
{
printf("Read 'end-of-file', exiting!\n");
break;
}
if ('\n' != c)
{
flush_input_stream(stdin);
}
if (!isdigit(c))
{
printf("%c is not a digit! Start over!\n", c);
continue;
}
if ('0' == c)
{
printf("Exit requested.\n");
break;
}
sum += c - '0';
printf("The current sum is %d.\n", sum);
} while (1);
return EXIT_SUCCESS;
}
void flush_input_stream(FILE * fp)
{
size_t i = 0;
int c;
while ((c = fgetc(fp)) != '\n' && c != EOF) /* Pull all until and including the next new-line. */
{
++i;
}
if (0 != i)
{
fprintf(stderr, "Flushed %zu characters from input.\n", i);
}
}