C programming для начинающих: часть 14 – операторы ветвления if/else

 

Предыдущая часть

Мы уже сталкивались с операторами if/else, например в часть 11 – if/else и проверка равенства.

В этой части начнём рассмотрение с такого кода:

#include <stdio.h>

int main(int argc, char **argv) {
        char agestring[10];
        int age;
        int bonus;

        printf("Enter your age : ");
        gets(agestring);
        age = atoi(agestring);
        if (age > 45) {
                bonus = 1000;
        } else {
                bonus = 500;
        }
        printf("Your age is %d, so your bonus is %d.\n", age, bonus);

        return(0);
}

Проверяем его:

[simterm]

$ gcc if_else.c -o if_else
$ ./if_else 
Enter your age : 234
Your age is 234, so your bonus is 1000.

[/simterm]

В этой программе мы просим пользователя ввести возраст и вносим его в переменную agestring с помощью функции gets().

Примечание: Why is the gets function so dangerous that it should not be used?

Далее, т.к. agestring является массивом символов:

...
char agestring[10];
...

То нам необходимо выполнить приведение типа к integer, т.к. в тесте мы используем целочисленный тип данных (45):

...
if (age > 45)
...

Приведение типа мы выполняем с помощью функции atoi(), после чего результат присваивается переменной типа int с именем age:

...
        int age;
...
        age = atoi(agestring);
...

Однако – тут существует проблема: что если пользователь введёт данные, которые не могут быть приведены к int?

Например:

[simterm]

$ ./if_else
Enter your age : ten
Your age is 0, so your bonus is 500.

[/simterm]

Обратите внимание:

Your age is 0

Т.к. atoi() не смогла выполнить приведение типа – она вернула 0, следовательно age == 0, и в тесте мы проверяем условие if (0 > 45), что является совсем не тем результат, которого мы ожидали.

Самое простое решение в данном примере – это выполнить сначала проверку: не является ли age равным нулю, и если нет – то продолжать сравнение, в противном случае – выйти.

Для этого используем вложенные операторы ветвления. Перепишем немного программу:

#include <stdio.h>

int main(int argc, char **argv) {
        char agestring[10];
        int age;
        int bonus;

        printf("Enter your age : ");
        gets(agestring);
        age = atoi(agestring);
        if (age == 0) {
                printf("You entered an invalid age, so your bonus cannot be calculated.\n");
        } else {
                if (age > 45) {
                        bonus = 1000;
                } else {
                        bonus = 500;
                }
                printf("Your age is %d, so your bonus is %d.\n", age, bonus);
        }

        return(0);
}

А вот и пример вложенного ветвления:

...
        if (age == 0) {
                printf("You entered an invalid age, so your bonus cannot be calculated.\n");
        } else {
                if (age > 45) {
...

Сначала мы проверяем – не является ли age равным нулю, и если это не так – выполняем сравнение > 45:

...
else {
                if (age > 45) {
                        bonus = 1000;
                } else {
                        bonus = 500;
                }
                printf("Your age is %d, so your bonus is %d.\n", age, bonus);
        }
...

Проверяем – как это работает:

[simterm]

$ ./if_else 
Enter your age : 10
Your age is 10, so your bonus is 500.
$ ./if_else 
Enter your age : ten
You entered an invalid age, so your bonus cannot be calculated.

[/simterm]

Однако будьте осторожны с множественными вложенными проверками, так как это приводит усложеннию кода, что черевато ошибками, особенно если вы используете несколько уровней вложенности.

Продолжение – часть 15 – проблемы gets() и fgets().