【问题标题】:Comparing unsigned char with integer literal将 unsigned char 与整数文字进行比较
【发布时间】:2020-07-06 11:58:45
【问题描述】:
#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 和数字常量时,可能会发生两种情况:要么将数字常量转换为 UNSIGNED CHAR 并按字母顺序与 "voto" 进行比较,要么将 "voto" 转换为 INT 并得到与数字上的字面量相比。在这两种情况下,您都强制处理器执行强制转换,在第一种情况下,程序可能无法正常工作: 按字母顺序,这将是一个正确的顺序: 1 11 111 2 222 23 这里有 2 个结果大于 11 和 111,23 个结果大于 222。

这种比较不是总是导致 VOTO 被转换为 INT,而不是相反吗?而且,如果文字被转换为 UNISGNED CHAR,程序不会以同样的方式工作吗?

【问题讨论】:

  • 我一个字都听不懂你老师写了什么,你写了什么,但是voto是一个unsigned char,而%d格式说明符与scanf需要一个@987654326 @。你的编译器应该警告过你。只需将unsigned char voto; 替换为int voto; 即可。
  • (a) 您的老师是否评论了问题中显示的代码版本,准确地说? (b) 在 C 中,文字常量 111 的类型为 int,并且在比较中不会转换为 unsigned char,无论其他操作数的类型如何。
  • 是的。我使用 %d 所以我可以将一个整数从输入存储到 voto 变量
  • 这段代码是你的老师给你的和相关的评论,还是你提交的这段代码和老师对你写的评论的评论?
  • 第二个。

标签: c casting char


【解决方案1】:

如果这正是您提交的程序,那么您的老师没有很好地阅读您的代码。有一个完全不同的问题。

如果您写了scanf("%c", &amp;voto);,那么您老师的 cmets 将具有一定的意义,尽管它们似乎暗示 C 可能会将字符“1”转换为值 1,但事实并非如此。如果你真的只期望一个字符,你可以侥幸逃脱,虽然你必须改变你比较 voto 与字符文字的所有其他值,因为字符 '1' 的值,例如,是 49。无论如何,这是行不通的,因为您显然需要能够读取数字 10,即两个字符长。

但您是正确的,unsigned char 将转换为int

在您的实际程序中,或者至少在此处粘贴的程序中,您实际上已经编写了

scanf("%d", &voto);

这肯定是正确的。 %d 转换说明符必须有一个指向 int 的指针作为其对应的参数;因为它没有,所以它是未定义的行为。在实践中,scanf 可能会将给定指针视为指向不存在的int 的指针,这意味着恰好位于voto 附近的局部变量将被覆盖。 (可能会发生更糟糕的事情;这只是给你一个想法。)

【讨论】:

  • “恰好在 voto 附近的局部变量将被覆盖”:这可能会发生,但实际上它只是未定义的行为。
  • @Jabberwocky:很公平。已编辑。
【解决方案2】:

对于初学者来说,scanf 的调用是不正确的,因为使用了不正确的转换说明符 %d 和 unsigned char 类型的对象。

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

即使您将整数常量转换为 unsigned char 类型,通常的算术转换也将应用于关系运算或比较的两个操作数。这意味着在整数常量具有 int 类型或将整数常量转换为 unsigned char 类型之后,由于整数提升(这是通常算术转换的一部分),两个操作数都将转换为 int 类型) 并且将比较操作数的整数值。这与字母比较没有共同之处,因为整数常量可以有任何值,并且很明显,例如字符 'A' 的 ASCII 值等于 65 小于整数常量 111。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-04
    • 2015-10-09
    • 2021-12-28
    • 1970-01-01
    相关资源
    最近更新 更多