调用函数时参数太少(c)

时间:2018-04-05 23:08:13

标签: c function arguments

我对此仍然是一个荒谬的新手,但我想我已经很好地得到了这段代码。这个程序根据我的课程大纲将一些硬编码等级变成大小并将它们转换成字母形式。在gradePrint函数中,strcopy_s函数都会在调用函数时给出“参数太少”错误。

以下是代码:

#include<stdio.h>
#include <string.h>
#include <stdlib.h>

int grade(name,attendance, assignments, programs, quizzes, exam) // this takes the int values from the main function
{
    int attendancePercent, assignmentsPercent, programsPercent, quizzesPercent, examPercent; // makes the percentage values
    int finalGrade;

    attendancePercent = attendance * 5 / 100;
    assignmentsPercent = assignments * 20 / 100;
    programsPercent = programs * 30 / 100;
    quizzesPercent = quizzes * 25 / 100;
    examPercent = exam * 20 / 100;
    finalGrade = (attendancePercent + assignmentsPercent + programsPercent + quizzesPercent + examPercent +2);
    finalGrade = gradePrint(name, finalGrade); // this sends the finalGrade and the name over to gradePrint

}





int gradePrint(name, finalGrade) {

    char letter[100];


    if (finalGrade > 105 || finalGrade < 0) { printf("%d is not a valid grade.\n", finalGrade); }
    if (finalGrade <= 105 && finalGrade >= 97) { strcpy_s(letter, "A+"); }
    if (finalGrade <= 96 && finalGrade >= 94) { strcpy_s(letter, "A"); }
    if (finalGrade <= 93 && finalGrade >= 90) { strcpy_s(letter, "A-"); }
    if (finalGrade <= 89 && finalGrade >= 87) { strcpy_s(letter, "B+"); }
    if (finalGrade <= 86 && finalGrade >= 84) { strcpy_s(letter, "B"); }
    if (finalGrade <= 83 && finalGrade >= 80) { strcpy_s(letter, "B-"); }
    if (finalGrade <= 79 && finalGrade >= 77) { strcpy_s(letter, "C+"); }
    if (finalGrade <= 76 && finalGrade >= 74) { strcpy_s(letter, "C"); }
    if (finalGrade <= 73 && finalGrade >= 70) { strcpy_s(letter, "C-"); }
    if (finalGrade <= 69 && finalGrade >= 60) { strcpy_s(letter, "D"); }
    if (finalGrade < 60) { strcpy_s(letter, "F"); }


    printf("%s\t", name);
    printf("Grade: %d\n", finalGrade);

}




int main() // individual values are put into main function
{

    char personOne, personTwo,personThree,personFour,personFive,personSix,personSeven,personEight,personNine;
    char name;



    personOne = grade("Adams, Tom",95, 93, 95, 99, 94); //each person all the way down recalls the grade function
    personTwo = grade("Curry, Jane",95, 85, 88, 87, 89);
    personThree = grade("Franklin, John",70, 50, 65, 50, 57);
    personFour = grade("George, Pat",85, 87, 81, 82, 88);
    personFive = grade("Keene, Mary",85, 72, 75, 68, 75);
    personSix = grade("Kraft, Martin",80, 85, 80, 88, 93);
    personSeven = grade("Martin, James",75, 65, 65, 52, 55);
    personEight = grade("Oakley, Ann",95, 85, 95, 88, 92);
    personNine = grade("Smith, Luke",95, 85, 75, 81, 75);
    system("pause");

}

我花了整个下午试图解决这个问题,在这里查看其他问题等等。答案可能正在盯着我,但我看不到它。有人可以帮忙吗?任何建议表示赞赏,提前谢谢

1 个答案:

答案 0 :(得分:2)

在我们开始之前的一些想法

(这个序言是我的意见。)

虽然C的旧标准允许int在您未明确声明类型的情况下(例如,函数的返回值,函数的参数等),因此默认类型为#include <stdio.h> int calc_final_grade( int attendance, int assignments, int programs, int quizzes, int exam); const char *grade_to_letters(int grade); int main() { printf("Name: %s, Grade: %s\n", "Tom, Adams", grade_to_letters(calc_final_grade(95, 93, 95, 99, 94))); return 0; /* successfully finished */ } int calc_final_grade( int attendance, int assignments, int programs, int quizzes, int exam) { /* TODO calculate something */ return 100; /* just return a value for now */ } const char *grade_to_letters(int grade) { const char result[] = "A+"; /* TODO: actually do the conversion of grade to letters */ /* FIXME: trouble with `return result` is we are returning a * memory address value (where "A+" is stored, but it's local to * this function) so by the time our main function tries to * _read_ the value at this memory address to print it, * the function context has been lost and its * contents would've disappeared from under us */ return result; } 我们总是希望避免这种做法,因为它可能导致C语言编译器关于变量性质的错误假设,从而导致意外结果。虽然 C 可能是所有语言中最强大的,但它也非常无情,而你 告诉它你想要的一切去做。它假定你知道你在做什么。因此,避免错误的最佳方法是明确并创建小的有意义的代码块并将它们编织在一起。

实际答案

让我们考虑一下你想如何继续下去。

首先让我们将问题分成两个简单的子问题:

  1. 我们希望获得给定成绩的相应字母。

  2. 我们需要根据每个类别的成绩确定每个人的加权最终成绩。

  3.   

    Side Note :这就是您想要创建(或选择不创建函数)的方式:注意,我建议我们为特定的&#34;创建函数。改变&#34;但我故意避免使用函数来执行程序化的东西(例如打印出来的东西)。

    第1步 - 整体结构

    首先让我们创建一个具有空功能所需结构的整体程序(他们不做任何有用的事情,但我们希望下一步做到这一点)

    main

    上面的程序足以让我们构建出来,除了让我们解决grade_to_letters中的内存问题。

    我们需要一个地方来保存成绩,但是因为我们要保存的是一个字符串(不是基本的C类型)我们不能只按值返回它,我们必须将它存储在某个地方并返回我们所在的地址存储它。此外,我们存储它的地方必须在尝试使用它的程序部分的的上下文或范围内有效。

    因此,我们为我们想要使用的函数范围内的等级字母创建了一个位置(在我们的例子中,我们将其打印在grade_to_letters中)将此点的地址传递给grade_to_letters函数,以实际用作其结果的存储。

    这意味着,首先grade_to_letters必须接受商店内容的地址 - 让我们这样做:

    因此我们更改\0的定义以接受结果的位置,在我们的示例中,我们希望它足以容纳三个字符(字母,修饰符和终止const char *grade_to_letters( char result[3], /* a place to store the results */ ...); /* see below */ 字符的字符串) :

    const char *grade_to_letters(char result[3], unsigned int grade) 
    
      

    请注意,现在我们不必为结果声明一个局部变量,我们已经有了一个位置(虽然注意到我们仍然可以返回结果!);

         

    我们还可以注意到我们的成绩永远不会是负数,所以我们将它们设为无符号整数。所以我们的原型变成了:

    const char *grade_to_letters(char result[3], unsigned int grade) 
    {
          /* set result to an error string XX */
          result[0] = result[1] = '?'; result[2] = 0;
    
          if (grade > 100) 
                 return result; /* error string ?? */
    
    
          result[1] = '\0'; /* for simple grades this is `\0` */
    
          result[0] = 'F';                 /* everyone fails */
          if(grade >= 60) result[0] = 'D'; /* or gets a D */
          if(grade >= 70) result[0] = 'C';
          if(grade >= 80) result[0] = 'B'; 
          if(grade >= 90) result[0] = 'A';
    
          /* TODO: figure out a way to do +/- and store it at result[1] */
    
          return result; 
    }
    

    第2步 - 实施grade_to_letters

    现在我们可以继续创建一个简单的grade_to_letters:

    grade_to_letters

    测试#include <stdio.h> int calc_final_grade( int attendance, int assignments, int programs, int quizzes, int exam); const char *grade_to_letters(char result[3], unsigned int grade); /* We change the main function to test the grade_to_letters * scenarios */ int main() { char result[3]; /* storage for letters */ /* printf("Name: %s, Grade: %s\n", "Tom, Adams", grade_to_letters(result, calc_final_grade(95, 93, 95, 99, 94))); */ /* test out different scenarios */ printf("%3d: %2s\n", 100, grade_to_letters(result, 100)); printf("%3d: %2s\n", 98, grade_to_letters(result, 98)); printf("%3d: %2s\n", 94, grade_to_letters(result, 94)); printf("%3d: %2s\n", 90, grade_to_letters(result, 90)); printf("%3d: %2s\n", 88, grade_to_letters(result, 88)); printf("%3d: %2s\n", 83, grade_to_letters(result, 83)); printf("%3d: %2s\n", 77, grade_to_letters(result, 77)); printf("%3d: %2s\n", 75, grade_to_letters(result, 75)); printf("%3d: %2s\n", 71, grade_to_letters(result, 71)); printf("%3d: %2s\n", 65, grade_to_letters(result, 65)); printf("%3d: %2s\n", 55, grade_to_letters(result, 55)); /* check boundaries (we should get ?? as a result) */ printf("%3d: %2s\n", 105, grade_to_letters(result, 105)); printf("%3d: %2s\n", -38, grade_to_letters(result, -38)); return 0; /* successfully finished */ } int calc_final_grade( int attendance, int assignments, int programs, int quizzes, int exam) { /* TODO calculate something */ return 100; /* just return a value for now */ } const char *grade_to_letters(char result[3], unsigned int grade) { /* set result to an error string '??' */ result[0] = result[1] = '?'; result[2] = 0; /* always terminate the string */ if (grade > 100) return result; result[1] = 0; /* for simple grades this is also `\0` */ result[0] = 'F'; /* everyone fails */ if(grade >= 60) result[0] = 'D'; /* or gets a D */ if(grade >= 70) result[0] = 'C'; if(grade >= 80) result[0] = 'B'; if(grade >= 90) result[0] = 'A'; /* TODO: figure out a way to do +/- and store it at result[1] */ return result; }

    %

    添加对+/-

    的支持

    请注意,当分数的单位部分分别为[7,9]或[0,3]时间间隔时,仅添加+或 - 。首先,我们必须让单位部分。如果我们在除以10之后获得等级的剩余部分(例如87/10 = 8 R 7)并且我们希望其余的7在这里,那么这很容易;我们可以弄清楚+或 - 。

    C中的余数函数是 /* returns '+' / '-' or 0 depending on how high the grade's units value is */ char plus_minus(unsigned int grade) { unsigned int remainder = grade % 10; /* get the remainder */ if (remainder >= 7) return '+'; /* 7,8,9 */ if (remainder <= 3) return '-'; /* 0,1,2,3 */ return 0; /* return `\0` char for 4,5,6 */ } 运算符;所以看看这个片段:

    const char *grade_to_letters(char result[3], unsigned int grade)
    {
          /* set result to an error string ?? */
          result[0] = result[1] = '?';
          result[2] = 0; /* string terminator */
    
          if (grade > 100)
                 return result;
    
    
          result[1] = 0;
          result[0] = 'F';                 /* everyone fails */
    
          if(grade >= 60) result[0] = 'D'; /* or gets a D */
    
          if(grade >= 70) {  /* everyone above 70 */
            result[0] = 'C'; /* gets at least a C */
            result[1] = plus_minus(grade); /* and a possibly a plus or minus */
          }
    
          if(grade >= 80) result[0] = 'B';
          if(grade >= 90) result[0] = 'A';
    
          if(grade >= 100) 
                result[1] = '+'; /* edge case for 100% */
    
          return result;
    }
    

    我们将其添加到grade_to_letters函数中:

    plus_minus

    重要注意事项:

    1. 请注意,我们只将if(grade >= 70)放在它所属的C中!我们只需要在那里做!它适用于所有成绩级别BAB,因为A if(grade >= 100) result[1] = '+'; /* edge case for 100% */ 是子集(等级&gt; = 70)

    2. 当您运行程序以获得等级= 100的值时,您将无法获得A +!这是因为10完全划分100,所以有一个边缘情况:

      #include <stdio.h>
      
      int calc_final_grade(int attendance,
                   int assignments, int programs, int quizzes, int exam);
      
      const char *grade_to_letters(char result[3], unsigned int grade);
      char plus_minus(unsigned int grade);
      
      int main()
      {
          char result[3];     /* storage */
      
          /* printf("Name: %s, Grade: %s\n", "Tom, Adams",
             grade_to_letters(result, calc_final_grade(95, 93, 95, 99, 94))); */
      
          printf("%3d: %2s\n", 100, grade_to_letters(result, 100));
          printf("%3d: %2s\n", 98, grade_to_letters(result, 98));
          printf("%3d: %2s\n", 94, grade_to_letters(result, 94));
          printf("%3d: %2s\n", 90, grade_to_letters(result, 90));
          printf("%3d: %2s\n", 88, grade_to_letters(result, 88));
          printf("%3d: %2s\n", 83, grade_to_letters(result, 83));
          printf("%3d: %2s\n", 77, grade_to_letters(result, 77));
          printf("%3d: %2s\n", 75, grade_to_letters(result, 75));
          printf("%3d: %2s\n", 71, grade_to_letters(result, 71));
          printf("%3d: %2s\n", 65, grade_to_letters(result, 65));
          printf("%3d: %2s\n", 55, grade_to_letters(result, 55));
      
          printf("%3d: %2s\n", 155, grade_to_letters(result, 155));
          printf("%3d: %2s\n", -38, grade_to_letters(result, -38));
      
          return 0;       /* successfully finished */
      }
      
      int
      calc_final_grade(int attendance,
               int assignments, int programs, int quizzes, int exam)
      {
          /* TODO calculate something */
          return 100;     /* just return a value for now */
      }
      
      const char *grade_to_letters(char result[3], unsigned int grade)
      {
          /* set result to an error string XX */
          result[0] = result[1] = 'X';
          result[2] = 0;      /* always NUL terminate */
      
          if (grade > 100)
              return result;
      
          result[1] = 0;
          result[0] = 'F';    /* everyone fails */
      
          if (grade >= 60)
              result[0] = 'D';    /* or gets a D */
      
          if (grade >= 70) {
              result[1] = plus_minus(grade);
              result[0] = 'C';
          }
      
          if (grade >= 80)
              result[0] = 'B';
          if (grade >= 90)
              result[0] = 'A';
          if (grade >= 100)
              result[1] = '+';    /* edge case for 100% */
      
          /* TODO: figure out a way to do +/- and store it at result[1] */
      
          return result;
      }
      
      char plus_minus(unsigned int grade)
      {
          unsigned int remainder = grade % 10;    /* get the remainder */
      
          if (remainder >= 7)
              return '+'; /* 7,8,9 */
      
          if (remainder <= 3)
              return '-'; /* 0,1,2,3 */
      
          return 0;       /* return `\0` char for 4,5,6 */
      }
      
    3. 我们会在最后加上这个并测试整个事情。

      到目前为止,这是该计划:

      int calc_final_grade(int attendance,
                   int assignments, int programs, int quizzes, int exam)
      {
           return ( 5 * attendance 
                 + 20 * assignments
                 + 30 * programs
                 + 25 * quizzes
                 + 20 * exam) / 100;
      }
      

      第3步 - 计算最终成绩:

      让我们修复主要功能并测试单个学生的最终成绩计算。我们的职责是:

      main

      首先添加值然后将结果除以100会在最后给出一个更好的整数值(这里使用余数函数进行舍入可能是值得的;或者不是)

      测试评分功能:

      我们可以更改int main() { char result[3]; /* storage */ int grade; grade = calc_final_grade(100, 0, 0, 0, 0); printf("Name: %s, Grade: %s (%d)\n", "Attender", grade_to_letters(result, grade), grade); grade = calc_final_grade(0, 100, 0, 0, 0); printf("Name: %s, Grade: %s (%d)\n", "Homer worker", grade_to_letters(result, grade), grade); grade = calc_final_grade(0, 0, 100, 0, 0); printf("Name: %s, Grade: %s (%d)\n", "Programmer", grade_to_letters(result, grade), grade); grade = calc_final_grade(0, 0, 0, 100, 0); printf("Name: %s, Grade: %s (%d)\n", "Mr. Tester", grade_to_letters(result, grade), grade); grade = calc_final_grade(0, 0, 0, 0, 100); printf("Name: %s, Grade: %s (%d)\n", "Exam Wizard", grade_to_letters(result, grade), grade); return 0; /* successfully finished */ } 以测试我们的评分功能:

      {{1}}

      Step-5全部放在一起

      将这些放在一起留给读者练习

      最后的想法

      希望这能让您深入了解如何解决这类问题并开始思考它们。