Сравнение беззнакового символа с целочисленным литералом - PullRequest
0 голосов
/ 26 марта 2020
#include <stdio.h>

int main()
{
    unsigned char voto;

    printf("Inserire il voto (da 2 a 10): ");
    scanf("%d", &voto);

    printf("\n\n\n%d ", voto);

    if(voto > 1 && voto < 11)
    {
        printf("corrisponde al giudizio ", voto);

        switch(voto)
        {
            case 2:
            case 3:
            case 4:
            case 5:
                printf("INSUFFICIENTE");
                break;
            case 6:
                printf("SUFFICIENTE");
                break;
            case 7:
                printf("DISCRETO");
                break;
            case 8:
                printf("BUONO");
                break;
            case 9:
                printf("MOLTO BUONO");
                break;
            case 10:
                printf("OTTIMO");
                break;
        }
    } else
    {
        printf("non e' un voto valido!");
    }

    printf("\n\n----------------------------");


    return 0;
}

Я скопирую сообщение, которое отправил мне мой учитель:

Когда IF сравнивает CHAR и числовую c константу, могут произойти две вещи: любая числовая c константа преобразуется в неподписанный символ и сравнивается с «voto» в алфавитном порядке, или «voto» преобразуется в INT и сравнивается с литералом численно. В обоих случаях вы заставляете процессор выполнять приведение, и в первом случае программа может работать некорректно: в алфавитном порядке это будет правильный порядок: 1 11 111 2 222 23 Здесь 2 результата больше, чем 11 и 111, и 23 результаты больше 222.

Разве это сравнение не всегда приводит к тому, что VOTO будет приведен к INT, а не к другому? И если литерал конвертируется в UNISGNED CHAR, разве программа не будет работать так же?

Ответы [ 2 ]

3 голосов
/ 26 марта 2020

Если это именно та программа, которую вы отправили, ваш учитель не очень хорошо читает ваш код. Существует совсем другая проблема.

Если бы вы написали scanf("%c", &voto);, тогда комментарии вашего учителя имели бы определенный смысл, хотя, похоже, они подразумевают, что C может привести к тому, что символ '1' будет значение 1, что, конечно, не так. Если вы действительно ожидаете только один символ, вы можете избежать этого, хотя вам придется изменить все другие значения, с которыми вы сравниваете voto, на литералы символов, поскольку, например, значение символа '1' 49. В любом случае, это не сработает, потому что вам явно требуется умение читать число 10. Длина его составляет два символа.

Но вы правы, что unsigned char будет преобразовано в int.

В вашей действительной программе или, по крайней мере, той, что вставлена ​​здесь, вы на самом деле написали

scanf("%d", &voto);

, и это, безусловно, не правильно. Спецификатор преобразования %d должен иметь указатель на int в качестве соответствующего аргумента; поскольку это не так, это неопределенное поведение. На практике вполне вероятно, что scanf будет рассматривать данный указатель как указатель на несуществующий int, и это означает, что локальные переменные, которые находятся в окрестности voto, будут перезаписаны. (Хуже всего может случиться; это просто, чтобы дать вам представление.)

2 голосов
/ 26 марта 2020

Для начала вызов scanf некорректен, поскольку используется неверный спецификатор преобразования% d с объектом типа unsigned char.

unsigned char voto;
//...
scanf("%d", &voto);

Даже если вы приведете целочисленную константу к типу unsigned char обычные арифметические c преобразования будут применены к обоим операндам реляционной операции или сравнения. Это означает, что в случае, когда целочисленная константа имеет тип int или после приведения целочисленной константы к типу char без знака, оба операнда будут преобразованы в тип int из-за целочисленных повышений (что является частью обычной арифметики c преобразования), и целые значения операндов будут сравниваться. Это не имеет ничего общего с алфавитным сравнением, поскольку целочисленная константа может иметь любое значение, и очевидно, что, например, значение ASCII символа 'A' равно 65 меньше целочисленной константы 111.

...