0

我正在尝试完成一个实验室,在该实验室中,我必须根据结构链接列表中给出的课程信息计算总平均绩点 (GPA)。我正在尝试用适当的成绩点定义每个字母等级('A' = 4.0,“A-” = 3.7 ...)。课程成绩存储在字符数组中。我可以使用#define导数来定义字母等级 A、B、C、D、E,但我在定义 +/- 等级时遇到了麻烦。使用#define导数是完成这项任务的正确方法吗?如果是这样,有人能告诉我正确的语法吗?

/* Definition of a data node holding course information */
  struct course {
    int term;
    char name[15];
    char abbrev[20];
    float hours;
    char grade [4];
    char type[12];
    struct course *next;
  };



float gpa ( struct course *ptr )
{
  float totalhours;
  float gpa;
  float gradepoints;

  while (ptr != NULL )
    {
      totalhours += (ptr->hours);
      gradepoints = (ptr->hours * ptr->grade);
    }
  gpa = (gradepoints / totalhours);
}
4

2 回答 2

1

What you are looking for is a map, or a dictionary, which is not natively supported in C. You can implement a simple map for your use case as an array of structs as such:

struct GradeInfo {
  char *grade;
  float value;
};
struct GradeInfo GRADES[] = { {"A", 4.0}, {"A-", 3.7}, ..., {NULL, 0.0}};

Then loop over this array inside your for loop (fixing a few more bugs):

float gpa ( struct course *ptr )
{
  float totalhours = 0.0;
  float gradepoints = 0.0;

  for (; ptr; ptr = ptr->next)
    {
      float grade = -1.0;
      struct GradeInfo *info;
      for (info = GRADES; info->grade; ++info) {
        if (!strcmp(ptr->grade, info->grade)) {
          grade = info->value;
          break;
        }
      }
      if (grade < 0) {
        continue;
      }
      totalhours += (ptr->hours);
      gradepoints = (ptr->hours * ptr->grade);
    }
  if (!totalhours) {
    return 0.0;
  }
  return (gradepoints / totalhours);
}
于 2012-10-01T00:33:45.803 回答
0

What you want is string literals, not variables with those names ... you could define macros, but it just adds a pointless extra level since the mapping is fixed. e.g.,

// grade_string is a string read from the input
float grade_value;

if (strcmp(grade_string, "A") == 0)
    grade_value = 4.0;
else if (strcmp(grade_string, "A-") == 0)
    grade_value = 3.7;
etc.

There are a couple of more compact ways you can do this.

1) Create an array of mappings, e.g.,

struct {
    char*  string;
    double value; 
} grades = { {"A", 4.0}, {"A-", 3.7}, etc. };

and loop over this array, comparing the strings to grade_string and extracting the value. e.g.,

int ngrades = sizeof grades / sizeof *grades;
int i;
for(i = 0; i < ngrades; i++)
    if (strcmp(grades[i].string, grade_string) == 0)
    {
        grade_value = grade[i].value;
        break;
    }

if (i == ngrades)
    /* invalid grade */

2) Use a hash table. This would be advisable if you had a large number of mappings.

于 2012-10-01T00:27:15.207 回答