C Language
Перейти к началу страницы
Поиск…
Синтаксис
- return val; / * Возвращает из текущей функции. val может быть значением любого типа, которое преобразуется в возвращаемый тип функции. * /
- вернуть; / * Возвращает из текущей функции void. * /
- перерыв; / * Безусловно перескакивает за пределы («разрывается») итерационного заявления (цикл) или из самого внутреннего оператора switch. * /
- Продолжить; / * Безусловно переходит в начало итерационного заявления (цикл). * /
- goto LBL; / * Переход к метке LBL. * /
- LBL: statement / * любое утверждение в той же функции. * /
замечания
Это прыжки, которые интегрируются в C с помощью ключевых слов.
C также имеет другую конструкцию перехода, длинный прыжок , который указан с типом данных, jmp_buf
и вызовами библиотеки C, setjmp
и longjmp
.
Смотрите также
Использование goto для перехода из вложенных циклов
Выпрыгивание из вложенных циклов обычно требует использования логической переменной с проверкой этой переменной в циклах. Предположим, что мы итерируем по i
и j
, это может выглядеть так
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 */
}
}
Но язык C предлагает предложение goto
, которое может быть полезно в этом случае. Используя его с меткой, объявленной после циклов, мы можем легко вырваться из циклов.
size_t i,j;
for (i = 0; i < myValue; ++i) {
for (j = 0; j < mySecondValue; ++j) {
...
if(breakout_condition)
goto final;
}
}
final:
Однако часто, когда эта потребность приходит, return
может быть лучше использовано вместо этого. Эта конструкция также считается «неструктурированной» в теории структурного программирования.
Другая ситуация, когда goto
может быть полезной, - это прыжок в обработчик ошибок:
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;
Использование goto
сохраняет поток ошибок отдельно от обычного потока управления программой. Однако он также считается «неструктурированным» в техническом смысле.
Использование возврата
Возврат значения
Один часто используемый случай: возвращение из 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;
}
Дополнительные примечания:
Для функции, имеющей тип возврата как
void
(не включаяvoid *
или связанные типы), операторreturn
не должен иметь никакого связанного выражения; т.е. единственным допустимым оператором return будетreturn;
,Для функции, имеющей
void
типreturn
операторreturn
не должен появляться без выражения.Для
main()
(и только дляmain()
) явный операторreturn
не требуется (на C99 или новее). Если выполнение достигает завершения}
, возвращается неявное значение0
. Некоторые люди думают, что отказ от этогоreturn
- плохая практика; другие активно предлагают отказаться от этого.
Возвращение ничего
Возвращение из функции 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. */
}
Использование break и continue
Сразу же continue
чтение недопустимого ввода или break
на запросе пользователя или конце файла:
#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);
}
}