Поиск…


Синтаксис

  • 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;
}

Дополнительные примечания:

  1. Для функции, имеющей тип возврата как void (не включая void * или связанные типы), оператор return не должен иметь никакого связанного выражения; т.е. единственным допустимым оператором return будет return; ,

  2. Для функции, имеющей void тип return оператор return не должен появляться без выражения.

  3. Для 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);
  }
}


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow