【问题标题】:Handling and writing functions that return strings in c?在 c 中处理和编写返回字符串的函数?
【发布时间】:2025-12-20 22:45:16
【问题描述】:

我一直在努力处理一个调用返回字符串的函数的程序。我得到了一些似乎可行的想法,但程序仍然崩溃。这是部分代码。

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 ,然后崩溃。返回字符串的函数是成绩和课程评论。这里有代码。

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; 
}

所有这些返回字符串和程序编译和运行正常但崩溃。如何正确处理这些函数?

【问题讨论】:

  • 你之前问过几乎同样的问题:*.com/questions/4958758/…
  • 您不需要临时变量。只需写'return "A+"'
  • 在成绩中,您不需要指定低于 X 的成绩,因为程序的流程只会处理低于前一个成绩下限的条件。
  • 顺便说一句,不要将变量命名为temp,因为这不会增加可读性(例如temp1)。更好的名称可能是“grade_A_text”或“progress_text”。有时不需要变量:if (c &gt; 2.0) return "Progress"; else return "Stay Put";

标签: c string


【解决方案1】:

course_comment 在某些条件下没有明确的返回值。你不应该让这种情况发生;相反,如果没有其他评论,则返回一个空字符串。例如:

char *course_comment(float b)
{
     char *retake="Retake";
     if (b < 2.0) {
          return retake;
     }
     return "";
}

当函数返回时没有显式返回值,结果是未定义的。这通常意味着你的程序会崩溃。 (这实际上是最好的情况;最坏的情况是它不会崩溃,但会给您带来不可靠的结果。)

(顺便说一句,我相信您可以为您的字符串找到比temptemp1、...temp13 等更好的名称)

编辑:最初,我写道student_comment 有同样的问题,但这是我的错误。至少在目前的形式中,它总是返回一个指向有效字符串文字的指针。 (代码的格式化方式使得跟踪逻辑变得更加困难。我已经修复了格式。)

【讨论】:

  • ... 或者,正如上面有人指出的那样,直接返回文字,避免需要“临时”变量。好的回复; +1。
【解决方案2】:

您是否给出了函数 course_comment() 的完整定义?如果是这样,那你就有问题了。如果 b >= 2.0 会返回什么?

【讨论】:

    【解决方案3】:

    当 if 条件为假时,您忘记返回某些内容。例如

    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() 函数类似。 如果你打开编译器警告,编译器应该警告你——保持程序没有警告。

    【讨论】:

      【解决方案4】:

      把这个给你的教授:

      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 个字符串的数组,并使用分数作为数组的索引来检索成绩。同样,最佳解决方案取决于限制:空间或执行时间。

      【讨论】: