unicode of char misused for int



我正在编写一个读取学生等级的程序,无论是char还是int并将其存储在union中,然后打印出成绩为A或> 90的学生。

但是,当我尝试这样做时,我会得到意外的输出,因为该程序不知道我要比较哪一个(char或int)。

#include <stdio.h>
#include <stdlib.h>
union StuGrade {
    char charGrade;
    int intGrade;
};
struct Student {
    int ID;
    int typeOfGrade;
    union StuGrade grade;
};
int main () {
    const int size = 5; 
    struct Student *sList[size]; 
    for (int i = 0; i < size; i++) {
        sList[i] = (struct Student *)calloc(1, sizeof(struct Student));
        if (!sList[i]) {
            puts("Error allocating memory");
            return 1;
        }
        printf("Enter ID: "); 
        scanf("%d", &(sList[i]->ID)); 
        printf("0 for char grade or 1 for int grade: "); 
        scanf("%d", &(sList[i]->typeOfGrade));
        if (sList[i]->typeOfGrade) { 
            printf("Enter an int grade: ");
            scanf("%d", &(sList[i]->grade.intGrade)); 
        } else { 
            printf("Enter a char grade: ");
            scanf(" %c", &(sList[i]->grade.charGrade)); 
        }
    } //end for loop
    printf("n***Student(s) who take grade 'A' is/are***n");
    for (int i = 0; i < size; i++) {
        if (sList[i]->grade.charGrade == 'A') 
            printf("ID: %d nGrade: %c n", sList[i]->ID, sList[i]->grade.charGrade);
        else if (sList[i]->grade.intGrade >= 90) 
            printf("ID: %d nGrade: %d n", sList[i]->ID, sList[i]->grade.intGrade);
    }
    for (int i = 0; i < size; i++)
        free(sList[i]);
    return 0;
}

这是输出:

Enter ID: 1
0 for char grade or 1 for int grade: 0
Enter a char grade: A
Enter ID: 2
0 for char grade or 1 for int grade: 0
Enter a char grade: b
Enter ID: 3
0 for char grade or 1 for int grade: 1
Enter an int grade: 99
Enter ID: 4
0 for char grade or 1 for int grade: 1
Enter an int grade: 84
Enter ID: 5
0 for char grade or 1 for int grade: 1
Enter an int grade: 65
***Student(s) who take grade 'A' is/are***
ID: 1 
Grade: A 
ID: 2 
Grade: 98 
ID: 3 
Grade: 99 
ID: 5 
Grade: A 

在比较中使用等级类型:

  if (sList[i]->typeOfGrade == 0 && sList[i]->grade.charGrade == 'A') 
     printf("ID: %d nGrade: %c n", sList[i]->ID, sList[i]->grade.charGrade);
  else if (sList[i]->typeOfGrade == 1 && sList[i]->grade.intGrade >= 90) 
     printf("ID: %d nGrade: %d n", sList[i]->ID, sList[i]->grade.intGrade);

注意:我的原始答案使用了ASCII表,但是有人指出我应该使用UTF-8表。但是,对于此处描述的目的,两者都非常相似。但是,从技术上讲,编译器通常会使用UTF-8而不是ASCII,因此我已经编辑了答案以反映这一点。

ville-valtteri有一个很好的答案,但我也想解释发生了什么。

所以,请查看UTF-8表。

希望您应该知道,任何计算机上的每个字符都会翻译成一个数字。这是由上述表确定的。

在C和C 中,这些是同样处理的,因为我将数字分配给char:

char c = 65;

它将将其视为字母'A'

相反,如果我将字母'A'分配给int:

int i = int('A');

您最终获得了数字65

好吧,现在使用您的代码。让我们看一下您的第一个测试:

if (sList[i]->grade.charGrade == 'A')

您测试以查看该值是否为== to 'A'。请注意,您不检查类型,因此65对于此测试完全可以接受,即使您将其添加为INT ,因为您没有为此进行测试。您正在为'A'或其等效的65进行测试

现在,您的第二个测试:

else if (sList[i]->grade.intGrade >= 90) 

所以,如果不是字符级" A",那一定是int等级的权利吗?错误,因为没有测试是否是char等级,只是它不是字符级" A"。没有什么,您可以参加此测试。

这意味着字母'b'将进入此测试,该测试的值为98(再次请参见UTF-8表)。由于C和C 将数字和字母视为相同的(不是技术上的,而是关闭),因此它将其作为INT 98级测试,即使它打算是char等级。这意味着它通过您> = 90检查。

将我们带到Ville-Valtteri的解决方案,该解决方案是您支票中的等级类型。

 if (sList[i]->typeOfGrade == 0 && sList[i]->grade.charGrade == 'A') 
    printf("ID: %d nGrade: %c n", sList[i]->ID, sList[i]->grade.charGrade);
 else if (sList[i]->typeOfGrade == 1 && sList[i]->grade.intGrade >= 90) 
    printf("ID: %d nGrade: %d n", sList[i]->ID, sList[i]->grade.intGrade);

相关内容

最新更新