C++
Управление потоком
Поиск…
замечания
Проверьте тему циклов для разных типов циклов.
дело
Вводит метку case оператора switch. Операнд должен быть постоянным выражением и соответствовать условию переключения в типе. Когда оператор switch выполняется, он переходит к метке case с операндом, равным условию, если оно есть.
char c = getchar();
bool confirmed;
switch (c) {
case 'y':
confirmed = true;
break;
case 'n':
confirmed = false;
break;
default:
std::cout << "invalid response!\n";
abort();
}
переключатель
Согласно стандарту C ++,
Оператор
switch
приводит к тому, что управление передается одному из нескольких операторов в зависимости от значения условия.
Ключевое слово switch
следует в скобках условие и блок, который может содержать case
метки и необязательное по default
ярлык. Когда оператор switch выполняется, управление будет передано либо на метку case
либо на значение, соответствующее значению условия, если таковое имеется, или на метку по default
, если таковая имеется.
Условие должно быть выражением или объявлением, которое имеет либо целочисленный, либо тип перечисления, либо тип класса с функцией преобразования для целочисленного или перечисляемого типа.
char c = getchar();
bool confirmed;
switch (c) {
case 'y':
confirmed = true;
break;
case 'n':
confirmed = false;
break;
default:
std::cout << "invalid response!\n";
abort();
}
ловить
Ключевое слово catch
вводит обработчик исключений, то есть блок, в который будет передаваться элемент управления, когда выбрано исключение совместимого типа. Ключевое слово catch
следует за объявлением исключения в скобках, которое по форме похоже на объявление параметра функции: имя параметра может быть опущено, а разрешен эллипс ...
, который соответствует любому типу. Обработчик исключений будет обрабатывать исключение только в том случае, если его объявление совместимо с типом исключения. Дополнительные сведения см. В разделе catching exceptions .
try {
std::vector<int> v(N);
// do something
} catch (const std::bad_alloc&) {
std::cout << "failed to allocate memory for vector!" << std::endl;
} catch (const std::runtime_error& e) {
std::cout << "runtime error: " << e.what() << std::endl;
} catch (...) {
std::cout << "unexpected exception!" << std::endl;
throw;
}
дефолт
В операторе switch вводится метка, на которую будет вклиниваться, если значение условия не равно ни одному из значений меток case.
char c = getchar();
bool confirmed;
switch (c) {
case 'y':
confirmed = true;
break;
case 'n':
confirmed = false;
break;
default:
std::cout << "invalid response!\n";
abort();
}
Определяет конструктор по умолчанию, конструктор копирования, конструктор перемещения, деструктор, оператор присваивания копий или оператор переноса назначения, чтобы иметь поведение по умолчанию.
class Base {
// ...
// we want to be able to delete derived classes through Base*,
// but have the usual behaviour for Base's destructor.
virtual ~Base() = default;
};
если
Вводит оператор if. Ключевое слово if
должно сопровождаться условием в скобках, которое может быть выражением или объявлением. Если условие является правдоподобным, выполнение после условия будет выполнено.
int x;
std::cout << "Please enter a positive number." << std::endl;
std::cin >> x;
if (x <= 0) {
std::cout << "You didn't enter a positive number!" << std::endl;
abort();
}
еще
В первом подзадаче оператора if может следовать ключевое слово else
. Подкрепление после ключевого слова else
будет выполняться, когда условие ложно (то есть, когда первое подзадание не выполняется).
int x;
std::cin >> x;
if (x%2 == 0) {
std::cout << "The number is even\n";
} else {
std::cout << "The number is odd\n";
}
идти к
Переход к помеченной инструкции, которая должна находиться в текущей функции.
bool f(int arg) {
bool result = false;
hWidget widget = get_widget(arg);
if (!g()) {
// we can't continue, but must do cleanup still
goto end;
}
// ...
result = true;
end:
release_widget(widget);
return result;
}
вернуть
Возвращает управление от функции к вызывающему.
Если return
имеет операнд, операнд преобразуется в тип возвращаемого значения функции, а преобразованное значение возвращается вызывающему.
int f() {
return 42;
}
int x = f(); // x is 42
int g() {
return 3.14;
}
int y = g(); // y is 3
Если return
не имеет операнда, функция должна иметь тип возврата void
. В качестве специального случая функция void
-returning также может возвращать выражение, если выражение имеет тип void
.
void f(int x) {
if (x < 0) return;
std::cout << sqrt(x);
}
int g() { return 42; }
void h() {
return f(); // calls f, then returns
return g(); // ill-formed
}
Когда main
возвращает, std::exit
неявно вызывается с возвращаемым значением, и поэтому значение возвращается в среду выполнения. (Однако возврат из main
уничтожает автоматические локальные переменные, а вызов std::exit
напрямую не выполняется).
int main(int argc, char** argv) {
if (argc < 2) {
std::cout << "Missing argument\n";
return EXIT_FAILURE; // equivalent to: exit(EXIT_FAILURE);
}
}
бросать
Когда
throw
происходит в выражении с операндом, его эффект заключается в том, чтобы выдать исключение , которое является копией операнда.void print_asterisks(int count) { if (count < 0) { throw std::invalid_argument("count cannot be negative!"); } while (count--) { putchar('*'); } }
Когда
throw
происходит в выражении без операнда, его эффект заключается в том, чтобы перебросить текущее исключение . Если не существует текущего исключения, вызываетсяstd::terminate
.try { // something risky } catch (const std::bad_alloc&) { std::cerr << "out of memory" << std::endl; } catch (...) { std::cerr << "unexpected exception" << std::endl; // hope the caller knows how to handle this exception throw; }
Когда
throw
происходит в деклараторе функции, он вводит спецификацию динамических исключений, в которой перечислены типы исключений, которые функция разрешает распространять.// this function might propagate a std::runtime_error, // but not, say, a std::logic_error void risky() throw(std::runtime_error); // this function can't propagate any exceptions void safe() throw();
Спецификации динамических исключений устаревают с C ++ 11.
Обратите внимание, что первые два использования throw
перечисленные выше, представляют собой выражения, а не выражения. (Тип выражения throw void
.) Это позволяет вложить их в выражения, например:
unsigned int predecessor(unsigned int x) {
return (x > 0) ? (x - 1) : (throw std::invalid_argument("0 has no predecessor"));
}
пытаться
Ключевое слово try
сопровождается блоком или списком инициализатора конструктора, а затем блоком (см. Здесь ). За блоком try следует один или несколько блоков catch . Если исключение распространяется из блока try, каждый из соответствующих блоков catch после блока try имеет возможность обрабатывать исключение, если типы совпадают.
std::vector<int> v(N); // if an exception is thrown here,
// it will not be caught by the following catch block
try {
std::vector<int> v(N); // if an exception is thrown here,
// it will be caught by the following catch block
// do something with v
} catch (const std::bad_alloc&) {
// handle bad_alloc exceptions from the try block
}
Условные структуры: if, if..else
если и еще:
он использовал, чтобы проверить, возвращает ли данное выражение true или false и действует как таковое:
if (condition) statement
условием может быть любое допустимое выражение C ++, которое возвращает то, что проверяется на правду / ложь, например:
if (true) { /* code here */ } // evaluate that true is true and execute the code in the brackets
if (false) { /* code here */ } // always skip the code since false is always false
условие может быть любым, функцией, переменной или сравнением, например
if(istrue()) { } // evaluate the function, if it returns true, the if will execute the code
if(isTrue(var)) { } //evalute the return of the function after passing the argument var
if(a == b) { } // this will evaluate the return of the experssion (a==b) which will be true if equal and false if unequal
if(a) { } //if a is a boolean type, it will evaluate for its value, if it's an integer, any non zero value will be true,
если мы хотим проверить несколько выражений, мы можем сделать это двумя способами:
используя двоичные операторы :
if (a && b) { } // will be true only if both a and b are true (binary operators are outside the scope here
if (a || b ) { } //true if a or b is true
используя if / ifelse / else :
для простого переключателя, если или иначе
if (a== "test") {
//will execute if a is a string "test"
} else {
// only if the first failed, will execute
}
для нескольких вариантов:
if (a=='a') {
// if a is a char valued 'a'
} else if (a=='b') {
// if a is a char valued 'b'
} else if (a=='c') {
// if a is a char valued 'c'
} else {
//if a is none of the above
}
однако следует отметить, что вместо этого вы должны использовать « switch », если ваш код проверяет значение той же переменной
Операторы перехода: break, continue, goto, exit.
Инструкция по разрыву:
Используя break, мы можем оставить цикл, даже если условие для его конца не выполняется. Его можно использовать для завершения бесконечного цикла или для его завершения до его естественного конца
Синтаксис
break;
Пример : мы часто используем break
в случаях switch
, т. Е. После того, как переключатель i i удовлетворяется, выполняется блок кода этого условия.
switch(conditon){
case 1: block1;
case 2: block2;
case 3: block3;
default: blockdefault;
}
в этом случае, если выполняется случай 1, выполняется блок 1, то, что мы действительно хотим, это только обработанный блок1, но вместо этого, когда блок1 обрабатывается оставшимися блоками, блок2, block3 и blockdefault также обрабатываются, хотя только 1-й случай был насыщен . Чтобы избежать этого, мы используем break в конце каждого блока, например:
switch(condition){
case 1: block1;
break;
case 2: block2;
break;
case 3: block3;
break;
default: blockdefault;
break;
}
поэтому обрабатывается только один блок, и управление выходит из цикла переключателя.
break также может использоваться в других условных и не условных циклах, например, if
, в while
for
т. д .;
пример:
if(condition1){
....
if(condition2){
.......
break;
}
...
}
Инструкция продолжения:
Инструкция continue приводит к тому, что программа пропускает остальную часть цикла в текущей итерации, как если бы конец блока оператора был достигнут, заставляя его перейти к следующей итерации.
Синтаксис
continue;
Пример рассмотрим следующее:
for(int i=0;i<10;i++){
if(i%2==0)
continue;
cout<<"\n @"<<i;
}
который производит выход:
@1
@3
@5
@7
@9
i этот код всякий раз, когда выполняется условие i%2==0
continue
обрабатываться, это заставляет компилятор пропустить весь оставшийся код (печать @ и i), а инструкция increment / decment цикла выполняется.
Инструкция goto:
Это позволяет совершать абсолютный переход к другой точке программы. Вы должны использовать эту функцию тщательно, так как ее выполнение игнорирует ограничения типа вложения. Точка назначения идентифицируется меткой, которая затем используется как аргумент для инструкции goto. Метка состоит из допустимого идентификатора, за которым следует двоеточие (:)
Синтаксис
goto label;
..
.
label: statement;
Примечание. Использование инструкции goto сильно обескуражено, поскольку сложно отслеживать поток управления программой, что затрудняет понимание программы и ее трудно изменить.
Пример :
int num = 1;
STEP:
do{
if( num%2==0 )
{
num = num + 1;
goto STEP;
}
cout << "value of num : " << num << endl;
num = num + 1;
}while( num < 10 );
выход :
value of num : 1
value of num : 3
value of num : 5
value of num : 7
value of num : 9
всякий раз, когда выполняется условие num%2==0
, goto отправляет управление исполнением в начало цикла do-while
while.
Функция выхода:
exit
- это функция, определенная в cstdlib
. Цель exit
- завершить работу программы с определенным кодом выхода. Его прототип:
void exit (int exit code);
cstdlib
определяет стандартные коды выхода EXIT_SUCCESS
и EXIT_FAILURE
.