计算没有数组的学生的GPA

时间:2018-05-07 06:37:38

标签: 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\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);
}

3 个答案:

答案 0 :(得分:1)

尝试使用 indeterminate value (意味着未初始化)访问变量会调用 Undefined Behavior ,并且代码的有效操作将在此时停止。它似乎可以正常工作或SegFault或其间的任何内容。

要避免未初始化的值,请始终初始化它们 - 尤其是在您刚开始编程时。 (它会让你自己拯救......),例如

    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;

main的正确声明为int main (void)int main (int argc, char **argv)(您将看到使用等效char *argv[]编写的声明)。 注意: maintype int的函数,它返回一个值。见:C11 Standard §5.1.2.2.1 Program startup p1 (draft n1570)。另见:See What should main() return in C and C++?

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

必须每次都检查scanf返回,并确认返回次数等于您请求的转化次数 - 否则为匹配输入失败(或通过生成手册EOF取消用户)。这是确保您处理有效数据而不是进一步调用 Undefined Behavior (或将自己投入无限输入循环)的唯一方法。每次输入后,您必须始终清空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;
}

(你能弄明白为什么if (scanf (" %c", &c) != 1)只能意味着用户取消了输入吗?)

示例使用/输出

注意:下面有意输入无关字符,以提供代码的简单添加如何安全处理它们的示例。 (尝试使用原始代码输入以下内容,看看会发生什么)

$ ./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

仔细看看,如果您有其他问题,请告诉我。

答案 1 :(得分:0)

初始化ctotstot并重新定位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);
}

基于@mch@David C. Rankin

的评论

答案 2 :(得分:0)

应将插槽+ =得分修改为插槽+ = 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);
}