Оператор Case не выводит правильно? - PullRequest
2 голосов
/ 01 ноября 2011

Это очень странно, но ниже приведено мое утверждение:

switch($grade){
    case ($average >70):
    $grade = 'A';
    break;
    case ($average >=60 && $average <=69):
    $grade = 'B';
    break;
    case ($average >=50 && $average <=59):
    $grade = 'C';
    break;

};

Так что, если его 70+, это класс А, 60-69 класс В, 50-59 класс С.

Но вместо этого он выдает: 60+ класс A, 50-59 класс B, 40-49 класс C.

Почему это происходит, потому что функция кажется правильной?

    echo "<p><strong>Average Mark:</strong> $average</p>";
    echo "<p><strong>Average Grade:</strong> $grade</p>";

Ответы [ 4 ]

6 голосов
/ 01 ноября 2011

Как уже упоминалось в комментариях, «условие» в случае должно быть статическим значением, а не логическим выражением.

Кроме того, значение, которое вы включаете (в вашем случае $grade), должно быть тем, которое вы тестируете. Вы, кажется, используете это как подсказку о том, какую переменную вы назначаете .

Самый простой способ исправить ваш код - использовать конструкцию if-elseif-else:

if ($average >70)
    $grade = 'A';
elseif ($average >=60 && $average <=69)
    $grade = 'B';
elseif ($average >=50 && $average <=59)
    $grade = 'C';

Однако, чтобы быть извращенным и проиллюстрировать, как работает оператор switch, вы также можете сделать следующее:

switch(true){
    case ($average >70):
        $grade = 'A';
        break;
    case ($average >=60 && $average <=69):
        $grade = 'B';
        break;
    case ($average >=50 && $average <=59):
        $grade = 'C';
        break;
};

В этом примере я сравниваю значение true с каждым из случаев по очереди, где каждое из этих значений-дел на самом деле является результатом вычисления логического выражения. Первое выражение, значение которого соответствует true, сработает.

Возможно, это не сильно поможет, если вы не понимаете операторов switch.

Редактировать : Я только что заметил, что в логике есть пробел: что, если у кого-то в среднем ровно 70? Используя каскадный оператор, такой как switch или if-else, вы можете исключить часть избыточного (и в данном случае разрушающего) кода, таким образом:

if ($average >=70)
    $grade = 'A';
elseif ($average >=60)
    $grade = 'B';
elseif ($average >=50)
    $grade = 'C';
// ...
else
    $grade = 'F';

... и т. Д. До любой низшей ступени, которую вы используете.

2 голосов
/ 01 ноября 2011

Для тех из вас, кто говорит, поменяйте переменную, которую вы $average, ошибаетесь . Единственная причина, по которой он оценивает этот экземпляр, заключается в том, что switch использует произвольное сравнение , поэтому он говорит, что $average , установленный , истинно и сравнивает его с условными выражениями, которые все будет либо правда, либо ложь. Ранее, используя $grade, который был не установлен, оценивали переключение на false, потому что при свободном сравнении переменная, которая не установлена, выдаст уведомление и вернет false.

Хотя я рекомендую использовать if-then-else, правильный ответ на для использования оператора switch в этом случае следующий:

switch (true) {
    case ($average >= 70):
        $grade = 'A';
        break;
    case ($average >= 60 && $average < 70):
        $grade = 'B';
        break;
    case ($average >= 50 && $average < 60):
        $grade = 'C';
        break;
}

Как сказано выше, каждый оператор будет возвращать либо true, либо false. Идея состоит в том, что только один оператор должен когда-либо возвращать true одновременно, таким образом, оператор switch будет сопоставлять его значение true с одним оператором, который передал и выполняет только этот код, поскольку все остальные являются ложными и не совпадают .

1 голос
/ 01 ноября 2011

Вы должны использовать операторы if / else -:

if($average >70)
{
   $grade = 'A';
} else if($average >=60 && $average <=69)
{
   $grade = 'B';
} else if($average >=50 && $average <=59)
{
   $grade = 'C';
}
0 голосов
/ 01 ноября 2011

Редактировать: В качестве альтернативы вы можете вычислить значение $grade (50-100 в этом примере):

$grades = "CBAAA";
$grade = $grades[(int)($average/10) - 5];

Цикл переключения сравнивает случаи. Если вы действительно хотите использовать переключатель для работы (а не if / elseif / else), то вы можете использовать для этого переключатель, который сравнивается с TRUE:

switch(TRUE)
{
    case $average > 70:
        $grade = 'A';
        break;

    case $average >= 60 && $average <= 69:
        $grade = 'B';
        break;

    case $average >= 50 && $average <= 59:
        $grade = 'C';
        break;

    default:
        throw new Exception(sprintf('Unable to map average (%d) to a grade.', $average));
}
...