C Language
Instrukcje skoku
Szukaj…
Składnia
- return val; / * Zwraca bieżącą funkcję. val może być wartością dowolnego typu, który jest konwertowany na typ zwracany przez funkcję. * /
- powrót; / * Zwraca bieżącą funkcję void. * /
- przerwa; / * Bezwarunkowo przeskakuje poza koniec („wybucha”) instrukcji Iteration (pętla) lub poza najbardziej wewnętrzną instrukcję switch. * /
- kontyntynuj; / * Bezwarunkowo przeskakuje na początek instrukcji iteracji (pętla). * /
- goto LBL; / * Przeskakuje do oznaczenia LBL. * /
- LBL: instrukcja / * dowolna instrukcja w tej samej funkcji. * /
Uwagi
Są to skoki zintegrowane z C za pomocą słów kluczowych.
C ma również inną konstrukcję skok, skok w dal, który jest określony z typem danych, jmp_buf
i rozmów z biblioteki C, setjmp
i longjmp
.
Zobacz też
Używanie goto do wyskakiwania z zagnieżdżonych pętli
Wyskakiwanie z zagnieżdżonych pętli zwykle wymagałoby użycia zmiennej boolowskiej z kontrolą tej zmiennej w pętlach. Przypuśćmy, że mamy do iteracji po i
i j
, to może wyglądać następująco
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 */
}
}
Ale język C oferuje klauzulę goto
, która może być przydatna w tym przypadku. Używając go z etykietą zadeklarowaną po pętlach, możemy łatwo wydostać się z pętli.
size_t i,j;
for (i = 0; i < myValue; ++i) {
for (j = 0; j < mySecondValue; ++j) {
...
if(breakout_condition)
goto final;
}
}
final:
Jednak często, gdy pojawia się taka potrzeba, lepiej zamiast tego lepiej wykorzystać return
. Konstrukt ten jest również uważany za „nieustrukturyzowany” w teorii programowania strukturalnego.
Inną sytuacją, w której goto
może być przydatny, jest przeskakiwanie do programu obsługi błędów:
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;
Zastosowanie goto
utrzymuje przepływ błędów oddzielnie od normalnego przepływu sterowania programem. Jest jednak również uważany za „nieustrukturyzowany” w sensie technicznym.
Korzystanie ze zwrotu
Zwracanie wartości
Jeden często używany przypadek: powrót z 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;
}
Dodatkowe uwagi:
W przypadku funkcji mającej typ zwracany jako
void
(nie obejmującyvoid *
lub typów pokrewnych) instrukcjareturn
nie powinna mieć żadnego powiązanego wyrażenia; tj. jedyną dozwoloną instrukcją return byłbyreturn;
.W przypadku funkcji mającej nie
void
typreturn
instrukcjareturn
nie pojawi się bez wyrażenia.Dla
main()
(i tylko dlamain()
) nie jest wymagana wyraźna instrukcjareturn
(w C99 lub nowszym). Jeśli wykonanie osiąga zakończenie}
, zwracana jest wartość domyślna0
. Niektórzy uważają, że pominięcie tegoreturn
jest złą praktyką; inni aktywnie sugerują pominięcie tego.
Nic nie zwracam
Wracając z funkcji 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. */
}
Używaj break i kontynuuj
Natychmiast continue
czytanie przy nieprawidłowym wprowadzeniu lub break
na żądanie użytkownika lub koniec pliku:
#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);
}
}