C 计算不带数组的学生的平均成绩

C 计算不带数组的学生的平均成绩,c,C,我的代码有什么问题?它没有正确地给出值,当我插入q时,它没有正确地执行 #include<stdio.h> void main() { double a=0, x, ctot; double y, stot; char b, c='q'; double score=x*y; while(a<200){ printf("Enter no of Credits of the subject = "); scanf("%lf

我的代码有什么问题?它没有正确地给出值,当我插入q时,它没有正确地执行

#include<stdio.h>
void main()
{
    double a=0, x, ctot;
    double y, stot;
    char b, c='q';
    double score=x*y;
    while(a<200){
     printf("Enter no of Credits of the subject = ");
     scanf("%lf\n",&x);
     printf("Enter the score for the subject = ");
     scanf("%lf\n",&y);
     scanf("%c\n",&b);
    if(b=='q'){
            break;
    }else{

            ctot+=x;
            stot+=score;
            a++;
    }
}
    printf("GPA of the student = %f\n", stot/ctot);
}
#包括
void main()
{
双a=0,x,ctot;
双y型,匍匐;
字符b,c='q';
双倍得分=x*y;

当(a初始化
ctot
stot
并重新定位
score=x*y
时,您的代码将正常工作。请尝试此编辑的代码此操作正常:-

#include <stdio.h>
void main()
{
    double a = 0, x, ctot;
    double y, stot;
    char b, c = 'q';
    double score;

    ctot = 0;   // initialize ctot and stot    #ERROR1
    stot = 0;

    while (a < 200)
    {
        printf("\n Enter no of Credits of the subject = ");
        scanf("%lf", &x);
        printf("\n Enter the score for the subject = ");
        scanf("%lf", &y);
        getchar(); // to manage the addtional \n from scanf()

        score = x * y; //     computing score         #ERROR2

        scanf("%c", &b);

        if (b == 'q')
        {
            break;
        }
        else
        {

            ctot += x;
            stot += score;
            a++;
        }
    }
    printf("\n GPA of the student = %f", stot / ctot);
}
#包括
void main()
{
双a=0,x,ctot;
双y型,匍匐;
字符b,c='q';
双倍得分;
ctot=0;//初始化ctot和stot#ERROR1
stot=0;
而(a<200)
{
printf(“\n输入主题的学分数=”);
扫描频率(“%lf”、&x);
printf(“\n输入主题的分数=”);
扫描频率(“%lf”、&y);
getchar();//从scanf()管理附加\n
分数=x*y;//计算分数#错误2
scanf(“%c”和“b”);
如果(b='q')
{
打破
}
其他的
{
ctot+=x;
stot+=得分;
a++;
}
}
printf(“\n学生的平均成绩=%f”,stot/ctot);
}

根据和的评论,应将槽+=分数修改为槽+=x*y

#include<stdio.h>
void main()
{
    double a=0, x, ctot;
    double y, stot;
    char b, c='q';
    double score=x*y;
    while(a<200){
     printf("Enter no of Credits of the subject = ");
     scanf("%lf\n",&x);
     printf("Enter the score for the subject = ");
     scanf("%lf\n",&y);
     scanf("%c\n",&b);
    if(b=='q'){
            break;
    }else{

            ctot+=x;
            stot+=x*y;
            a++;
    }
}
    printf("GPA of the student = %f\n", stot/ctot);
}
#包括
void main()
{
双a=0,x,ctot;
双y型,匍匐;
字符b,c='q';
双倍得分=x*y;

而(a尝试访问具有不确定值(意味着未初始化)的变量会调用未定义的行为,并且代码的有效操作在此点停止。它可能看起来工作正常或
SegFault
或介于两者之间的任何操作

为了避免未初始化的值,请始终对它们进行初始化,尤其是在您刚开始编程时。(这将使您免于自己…),例如


main
的正确声明是
int main(void)
int main(int argc,char**argv)
(您将看到它是用等价的
char*argv[]
编写的)。注意:
main
类型int
的函数,它返回一个值。请参见:

虽然有一些古老的编译器和一些微控制器允许
void main()
,但这是一种非标准调用,任何有价值的编译器都会发出警告。(您在编译时启用了编译器警告,对吗?例如,gcc/clang的
-Wall-Wextra
或VS(
cl.exe
)的
/W3

必须每次检查
scanf
返回值,并验证返回值是否等于您请求的转换次数——否则会出现匹配或输入失败(或用户通过生成手动
EOF
取消)。这是确保您正在处理有效数据且不会进一步调用未定义行为(或陷入无休止的输入循环)的唯一方法。每次输入后必须始终清空
stdin
。格式字符串中的
'\n'
gimick将不起作用。清空
stdin
的简单方法是定义一个助手函数,以便在每次输入后调用该函数,以删除任何未读的无关字符或附加字符,例如

/* simple function to empty remaining chars in stdin */
void empty_stdin (void)     /* if no parameter - spcecify 'void' explicitly */
{
    int c = getchar();

    while (c != '\n' && c != EOF)
        c = getchar();
}
...
        printf ("Enter no of Credits of the subject = ");
        if (scanf ("%lf", &x) != 1) {   /* validate EVERY input */
            fprintf (stderr, "error: invalid input for 'x'.\n");
            return 1;
        }
        empty_stdin();  /* empty stdin, your \n gimick doesn't work */
总而言之,您可以执行以下类似操作:

#include <stdio.h>

/* simple function to empty remaining chars in stdin */
void empty_stdin (void)     /* if no parameter - spcecify 'void' explicitly */
{
    int c = getchar();

    while (c != '\n' && c != EOF)
        c = getchar();
}

int main (void) {

    int a = 0;          /* always initialize all variables - good practice */
    double ctot = 0.0,
        stot = 0.0,
        score = 0.0,
        x = 0.0,
        y = 0.0;
    char c = 0;

    for (; a < 200; a++) {  /* loop however you like */

        printf ("Enter no of Credits of the subject = ");
        if (scanf ("%lf", &x) != 1) {   /* validate EVERY input */
            fprintf (stderr, "error: invalid input for 'x'.\n");
            return 1;
        }
        empty_stdin();  /* empty stdin, your \n gimick doesn't work */

        printf ("Enter the score for the subject = ");
        if (scanf ("%lf", &y) != 1) {
            fprintf (stderr, "error: invalid input for 'y'.\n");
            return 1;
        }
        empty_stdin();

        score = x * y;  /* compute values each iteration */
        ctot += x;
        stot += score;

        /* prompt for additional credits? */
        printf ("add additional credits? (y/n): ");
        if (scanf (" %c", &c) != 1) {
            fprintf (stderr, "error: user canceled input.\n");
            return 1;
        }
        empty_stdin();

        if (c == 'n' || c == 'N')   /* you can use 'q', but (y/n) is fine */
            break;
    }
    printf ("\nGPA of the student = %f\n", stot/ctot);

    return 0;
}

仔细检查一下,如果您有进一步的问题,请告诉我。

ctot
stot
未初始化。
gcc-Wall file.c
给出6个警告。如果您在警告打开的情况下编译,您在运行程序之前通常会发现问题。
main
的正确声明是
int main(void)
int-main(int-argc,char**argv)
(您将看到它是用等效的
char*argv[]
编写的)。注意:
main
类型int
的函数,它返回一个值。请参见:。另请参见:您每次都必须检查
scanf
的返回,最好更改
%c“
使用所有前导空格,例如
%c
,否则每次都会发现输入被跳过且
b=10
。(你能找出原因吗?)除了
ctot
stot
未初始化之外,
double score=x*y;
(提示:当您试图读取未初始化的值时,会调用未定义的行为)一些解释和更好的代码格式可能会有所帮助。单击答案下方的“编辑”以修改/改进它。
#include <stdio.h>

/* simple function to empty remaining chars in stdin */
void empty_stdin (void)     /* if no parameter - spcecify 'void' explicitly */
{
    int c = getchar();

    while (c != '\n' && c != EOF)
        c = getchar();
}

int main (void) {

    int a = 0;          /* always initialize all variables - good practice */
    double ctot = 0.0,
        stot = 0.0,
        score = 0.0,
        x = 0.0,
        y = 0.0;
    char c = 0;

    for (; a < 200; a++) {  /* loop however you like */

        printf ("Enter no of Credits of the subject = ");
        if (scanf ("%lf", &x) != 1) {   /* validate EVERY input */
            fprintf (stderr, "error: invalid input for 'x'.\n");
            return 1;
        }
        empty_stdin();  /* empty stdin, your \n gimick doesn't work */

        printf ("Enter the score for the subject = ");
        if (scanf ("%lf", &y) != 1) {
            fprintf (stderr, "error: invalid input for 'y'.\n");
            return 1;
        }
        empty_stdin();

        score = x * y;  /* compute values each iteration */
        ctot += x;
        stot += score;

        /* prompt for additional credits? */
        printf ("add additional credits? (y/n): ");
        if (scanf (" %c", &c) != 1) {
            fprintf (stderr, "error: user canceled input.\n");
            return 1;
        }
        empty_stdin();

        if (c == 'n' || c == 'N')   /* you can use 'q', but (y/n) is fine */
            break;
    }
    printf ("\nGPA of the student = %f\n", stot/ctot);

    return 0;
}
$ ./bin/credits_grades
Enter no of Credits of the subject = 3
Enter the score for the subject = 90
add additional credits? (y/n): y
Enter no of Credits of the subject = 4 (seemed like 40)
Enter the score for the subject = 80 (thank god!)
add additional credits? (y/n): y
Enter no of Credits of the subject = 3
Enter the score for the subject = 85
add additional credits? (y/n): n

GPA of the student = 84.500000