我一直在努力学习一个调用返回字符串的函数的程序。我得到了一些似乎有用的想法,但程序仍然崩溃。这是代码的一部分。
printf("CSC 1100 %d %s %f %s\n ",fm_csc_1100[i] ,grades(fm_csc_1100[i]),gradepoint(fm_csc_1100[i]),course_comment(gradepoint(fm_csc_1100[i])) );
printf("CSK 1101 %d %s %f %s\n ",fm_csk_1101[i] ,grades(fm_csk_1101[i]),gradepoint(fm_csk_1101[i]),course_comment(gradepoint(fm_csk_1101[i])) );
该程序使用for循环显示学生的标记。标记已在程序的早期部分输入。函数调用工作正常,它显示第一个printf行,然后崩溃。返回字符串的函数是grade和course_ comment。这里有代码。
char *grades(int z)
{ char *temp3 = "A+";
char *temp4 = "A";
char *temp5 = "B+";
char *temp6 = "B";
char *temp7 = "C+";
char *temp8 = "C";
char *temp9 = "D+";
char *temp10 = "D";
char *temp11 = "E";
char *temp12 = "E-";
char *temp13 = "F";
if(z >= 90)
return temp3;
else if (z >= 80 && z<=89)
return temp4;
else if (z >= 75 && z<=79)
return temp5;
else if (z >= 70 && z<=74)
return temp6;
else if (z >= 65 && z<=69)
return temp7;
else if (z >= 60 && z<=64)
return temp8;
else if (z >= 55 && z<=59)
return temp9;
else if (z >= 50 && z<=54)
return temp10;
else if (z >= 45 && z<=49)
return temp11;
else if (z >= 40 && z<=44)
return temp12;
else
return temp13;
}
成绩很混乱,但我没有更好的方法。
char *course_comment(float b)
{ char *temp ="Retake";
if(b < 2.0)
return temp;
}
我在程序的后半部分调用的另一个函数虽然它没有到达那里因为它崩溃了。
char *student_comment(float c)
{
char *temp1 = "Progress";
char *temp2 ="Stay Put" ;
if (c > 2.0)
return temp1;
else
return temp2;
}
所有这些返回字符串,程序编译并运行正常但崩溃。我该如何正确处理这些功能?
答案 0 :(得分:2)
course_comment
在某些条件下没有明确的返回值。你永远不应该让这种情况发生;相反,如果没有其他评论要做,则返回一个空字符串。例如:
char *course_comment(float b)
{
char *retake="Retake";
if (b < 2.0) {
return retake;
}
return "";
}
当函数返回而没有显式返回值时,结果是未定义的。这通常意味着你的程序会崩溃。 (这实际上是最好的情况;最糟糕的情况是它不会崩溃,但会给你不可靠的结果。)
(顺便说一下,我确信你可以找到比temp
,temp1
,... temp13
等更好的字符串名称。)
编辑:最初,我写过student_comment
有同样的问题,但这是我的错误。至少在其当前形式中,它总是返回指向有效字符串文字的指针。 (代码格式化的方式使得跟踪逻辑变得更加困难。我已经修复了格式化。)
答案 1 :(得分:0)
您是否已给出函数course_comment()的完整定义?如果是这样,那你就有问题了。如果b> = 2.0,则返回什么?
答案 2 :(得分:0)
if条件为false时,您忘记返回某些内容。 e.g。
char *course_comment(float b)
{ char *temp ="Retake";
if(b < 2.0)
return temp;
}
应该是
char *course_comment(float b)
{
if(b < 2.0)
return "retake"
return "";
}
类似于student_comment()
功能。
如果打开编译器警告,编译器应警告您 - 保持程序没有警告。
答案 3 :(得分:0)
把这个给你的教授:
struct Grade_Range
{
const char * grade_text;
unsigned int lower_limit; // inclusive.
unsigned int upper_limit; // inclusive.
};
static const struct Grade_Range grade_table[] =
{
{"A+", 90, 100},
{"A ", 80, 89},
{"B+", 75, 79},
{"B ", 70, 74},
{"C+", 65, 69},
{"C ", 60, 64},
{"D+", 55, 59},
{"D ", 50, 54},
{"E ", 45, 49},
{"E-", 40, 44},
{"F ", 0, 39},
}
static const unsigned int NUM_GRADE_ENTRIES =
sizeof(grade_table) / sizeof(grade_table[0]);
const char * grades(unsigned int score)
{
static const char * unknown_score = "Unknown Score";
const char * result = unknown_score;
unsigned int index = 0;
for (index = 0; index < NUM_GRADE_ENTRIES; ++index)
{
if ((score >= grade_table[i].lower_limit)
&& (score <= grade_table[i].upper_limit))
{
break;
}
}
if (index < NUM_GRADE_ENTRIES)
{
score = grade_table[i].grade_text;
}
return score;
}
上述技术称为表查找。该函数是数据驱动的,意味着代码不会改变,数据决定了结果。此外,表的内容和大小可以更改,而无需更改功能。
清理,但可能不是最佳解决方案(如何定义最佳)。例如,可以删除其中一个限制并使用binary_search
函数。另一种方法是创建一个包含100个字符串的数组,并使用该分数作为数组的索引来检索等级。同样,最佳解决方案取决于限制:空间或执行时间。