Jump Statements
Using return
Section titled “Using return”Returning a value
Section titled “Returning a value”One commonly used case: returning from 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;}Additional notes:
Returning nothing
Section titled “Returning nothing”Returning from a void function
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. */}Using goto to jump out of nested loops
Section titled “Using goto to jump out of nested loops”Jumping out of nested loops would usually require use of a boolean variable with a check for this variable in the loops. Supposing we are iterating over i and j, it could look like this
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 */ }}But the C language offers the goto clause, which can be useful in this case. By using it with a label declared after the loops, we can easily break out of the loops.
size_t i,j;for (i = 0; i < myValue; ++i) { for (j = 0; j < mySecondValue; ++j) { ... if(breakout_condition) goto final; }}final:However, often when this need comes up a return could be better used instead. This construct is also considered “unstructured” in structural programming theory.
Another situation where goto might be useful is for jumping to an error-handler:
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;Use of goto keeps error flow separate from normal program control flow. It is however also considered “unstructured” in the technical sense.
Using break and continue
Section titled “Using break and continue”Immediately continue reading on invalid input or break on user request or end-of-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); }}Syntax
Section titled “Syntax”- return val; /* Returns from the current function. val can be a value of any type that is converts to the function’s return type. */
- return; /* Returns from the current void-function. */
- break; /* Unconditionally jumps beyond the end (“breaks out”) of an Iteration Statement (loop) or out of the innermost switch statement. */
- continue; /* Unconditionally jumps to the beginning of an Iteration Statement (loop). */
- goto LBL; /* Jumps to label LBL. */
- LBL: statement /* any statement in the same function. */
Remarks
Section titled “Remarks”These are the jumps that are integrated into C by means of keywords.
C also has another jump construct, long jump, that is specified with a data type, jmp_buf, and C library calls, setjmp and longjmp.