分段故障核心倾倒......?

时间:2011-11-06 08:09:32

标签: c segmentation-fault coredump

我正在努力实现这个目标:

  
    

编写一个接受三个用户输入的程序:作业标记,期中考试和期末考试        mark。

这些输入的类型为float,其值应介于0和100之间。

程序       应将最终成绩计算为百分比和字母等级。

    •最终成绩计算如下:作业20%,期中30%,期末考试50%。字母等级        计算如下:A(最终等级≥80%),B(80>最终等级≥70%),C(70>最终等级≥60%),             D(60>最终等级≥50%)和F(50>最终等级)。

    显示最终成绩和字母等级。

  

使用以下代码:

#include <stdio.h>

int checkMark(int);
float getMark();
float computeFinalGrade(float assign, float midterm, float finalExam, float finalGrade);
int computeLetterGrade(float);

int checkMark(int x)
{
    while(x<0 || x>100) //While x is a negative number:
    {
        printf("Invalid entry.Try again:");
        scanf("%d",&x);
    }

    if(x>0 && x<=100)//If x is a positive number:
        x=x;

    return x;
}

float getMark(void)
{
    float mark=0,assignMark=0,midMark=0,examMark=0,finalMark=0;
    char letterGrade;


    printf("Enter assignment grade:");
    scanf("%d",mark);

    checkMark(mark);
    assignMark=mark;

    printf("\nEnter midterm mark:");
    scanf("%f",&mark);

    checkMark(mark);
    midMark=mark;

    printf("\nEnter exam mark:");
    scanf("%f",&mark);

    checkMark(mark);
    examMark=mark;


    finalMark=computeFinalGrade(assignMark,midMark,examMark,finalMark);
    letterGrade=computeLetterGrade(finalMark);

    printf("The final grade for the course is %.1f, and the letter grade is %c.\n",finalMark,letterGrade);

    return 0;
}

float computeFinalGrade(float assign, float midterm, float finalExam, float finalGrade)
{
    assign=(float)0.2*assign;
    midterm=(float)0.3*midterm;
    finalExam=(float)0.4*finalExam;

    finalGrade=(float)assign+midterm+finalExam;
    return finalGrade;
}

int computeLetterGrade(float finalGrade)
{
    int grade;

        if(finalGrade>=80)
            grade=65;

        if(finalGrade<80)
            if(finalGrade>=70)
                grade=66;

        if(finalGrade<70)
            if(finalGrade>=60)
                grade=67;

        if(finalGrade<60)
            if(finalGrade>=50)
                grade=68;

        if(finalGrade<50)
            grade=70;

    return grade;
}

int main()
{
    getMark();

    return 0;
}

当我调试上面的程序并输入一个负数时,它给了我这个:

Enter assignment grade:123
Segmentation fault (core dumped)

我到底做错了什么?

4 个答案:

答案 0 :(得分:3)

这是你的问题:

scanf("%d",mark);

您需要传递变量的地址,并且说明符应为%f。尝试:

scanf("%f", &mark);

顺便提一下,有一个C FAQ

答案 1 :(得分:2)

如果您使用的是linux,请查看我的回答here。它是关于valgrind的,这个工具可以帮助调试段错误,内存泄漏等。

答案 2 :(得分:2)

对您的代码提出更多评论:

int checkMark(int x)
{
    while(x<0 || x>100) //While x is a negative number:
    {
        printf("Invalid entry.Try again:");
        scanf("%d",&x);
    }

    if(x>0 && x<=100)//If x is a positive number:
        x=x;

    return x;
}

应该是:

#define MIN_GRADE 0
#define MAX_GRADE 100

int checkMark(int x)
{
    while(x<MIN_GRADE || x>MAX_GRADE)
    {
        printf("Invalid entry.Try again:");
        scanf("%d",&x);
    }

    return x;
}

请注意我:

  • 删除了无用的评论

  • 删除了幻数(0和100)

  • 删除了无用的测试(如果退出while循环,则x位于{0,...,100}

  • 允许x等于0

  • 删除了幂等分配(x=x没有做任何有用的事情......)

然后:

float getMark(void)
{
    float mark=0,assignMark=0,midMark=0,examMark=0,finalMark=0;
    char letterGrade;

    printf("Enter assignment grade:");
    scanf("%d",mark);

^如其他人所述,您应在此%f中使用&markscanf

    checkMark(mark);

^如果您希望更新此代码中的mark = checkMark(mark);变量,则应为mark。这是因为mark的值传递给函数,而不是对变量mark的引用。另一个解决方案是通过这样的参考,但我认为你还没准备好这个:)

    assignMark=mark;

    printf("\nEnter midterm mark:");
    scanf("%f",&mark);

    checkMark(mark);
    midMark=mark;

    printf("\nEnter exam mark:");
    scanf("%f",&mark);

    checkMark(mark);
    examMark=mark;

^所有这些行的相同评论

    finalMark=computeFinalGrade(assignMark,midMark,examMark,finalMark);

^在这里传递finalMark作为参数是完全没用的。它应该只是finalMark = computeFinalGrade(assignMark, midMark, examMark);,你不觉得吗?

    letterGrade=computeLetterGrade(finalMark);

    printf("The final grade for the course is %.1f, and the letter grade is %c.\n",finalMark,letterGrade);

    return 0;
}

如前所述,您无需将finalGrade值传递给computeFinalGrade,您应该只使用以下内容:

float computeFinalGrade(float assign, float midterm, float finalExam)
{
    return 0.2*assign + 0.3*midterm + 0.4*finalExam; // this could even be a macro
}

最后,在computeLetterGrade中,您正在进行大量冗余测试,并且您的控制流被此变量赋值搞砸了,另外您应该使用char而不是{{1} }。试试这个:

int

你可能需要解决一些我没有提及的事情,但至少你应该通过一些修正来接近你的目标。

答案 3 :(得分:1)

当程序试图访问分配给程序的内存区域时,会发生分段错误。 scanf()期望变量的地址。在您的代码中,您将变量的值传递给scanf(),而不是cnicutar指出的地址。

scanf("%d",mark);

标记变量未初始化并且具有一些随机数据,它们被scanf视为内存位置,并且当它尝试写入该地址时...由于您访问了受限制的内存而发生分段错误。另外,mark是float变量,所以你应该使用%f说明符..

scanf("%f", &mark);