0

我是编程新手,最近发现这个网站可以帮助我自我教育。我正在尝试使用“C”制作一个程序,该程序会在我的书中提示三个不同类别的成绩,我遇到了 while 语句,并认为它们是我执行此操作的最佳选择。我当前的代码看起来像这样。

int countA;
int gradeA;
int totalA;
int weightA;
float averageA;

int countE;
int gradeE;
int totalE;
int weightE;
float averageE;

int countQ;
int gradeQ;
int totalQ;
int weightQ;
float averageQ;

totalA = 0;
countA = 0;

totalE = 0;
countE = 0;

totalQ = 0;
countQ = 0;

printf( "Enter Assignment Grade, -1 to end: "); /* prompt for input */
scanf( "%d", &gradeA );

while (gradeA != -1){
totalA = totalA + gradeA; /* add gradeA to totalA */
    countA = countA + 1;
        printf( "Enter Assignment Grade, -1 to end: "); /* prompt for input */
        scanf( "%d", &gradeA );
}
if (countA != 0) {
averageA = (float) totalA / countA;
printf( "total is %.2f\n", averageA );
}



printf( "Enter Exam Grade, -1 to end: "); /* prompt for input */
scanf( "%d", &gradeE );

while (gradeE != -1){
totalE = totalE + gradeE; /* add gradeE to totalE */
    countE = countE + 1;
        printf( "Enter Exam Grade, -1 to end: "); /* prompt for input */
        scanf( "%d", &gradeE );
}
if (countE != 0) {
averageE = (float) totalE / countE;
printf( "total is %.2f\n", averageE );
}


printf( "Enter Quiz Grade, -1 to end: "); /* prompt for input */
scanf( "%d", &gradeQ );

while (gradeQ != -1){
totalQ = totalQ + gradeQ; /* add gradeQ to totalQ */
    countQ = countQ + 1;
        printf( "Enter Quiz Grade, -1 to end: "); /* prompt for input */
        scanf( "%d", &gradeQ );
}
if (countQ != 0) {
averageQ = (float) totalQ / countQ;
printf( "total is %.2f\n", averageQ );
}

现在,在此之后我想要做的是再重复两次该过程,但是当我尝试运行 exe 时,我会运行第一部分,但由于某种原因,其他两部分根本没有出现。这是否只是为了限制 while 重复语句的作用?还是我在某个地方有错误。我试图弄清楚我做错了什么,但我只是看到了。

我还不太确定如何在此处正确发布,但这是我得到的输出示例。

这是我的输出示例,如您所见,它提示我输入第一个段,即分配部分,但在输入 -1 结束循环后,它只给我平均值并结束。

C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin>project1.exe
Enter Assignment Grade, -1 to end: 100
Enter Assignment Grade, -1 to end: 80
Enter Assignment Grade, -1 to end: 77
Enter Assignment Grade, -1 to end: 33
Enter Assignment Grade, -1 to end: 76
Enter Assignment Grade, -1 to end: 92
Enter Assignment Grade, -1 to end: -1
total is 76.33

我认为至少第一部分是有效的,但是在我得到总分后,我没有被提示进行下一次查看,然后询问考试成绩。

4

1 回答 1

2

您可能遇到的一个常见问题是输出缓冲。对于您的代码:

printf( "Enter Assignment Grade, -1 to end: "); /* prompt for input */
scanf( "%d", &gradeA );

您的终端可能不会将输出缓冲区刷新到屏幕。所以它会等待输入,但你可能看不到提示。要强制它,你可以这样做:

printf( "Enter Assignment Grade, -1 to end: "); /* prompt for input */
fflush(stdout);
scanf( "%d", &gradeA );

现在,这使得更多的重复。如果您只需要为每个循环编写一次提示而不是两次,那会更好。你可以通过gradeA在循环之前初始化为零来解决这个问题。然后循环内的第一个计算没有任何效果:

gradeA = 0;
totalA = -1;

while (gradeA != -1)
{
    totalA = totalA + gradeA;
    countA = countA + 1;
    printf( "Enter Assignment Grade, -1 to end: ");
    fflush(stdout);
    scanf( "%d", &gradeA );
}

请注意,我设置countE为 -1 以撤消在循环顶部递增它的事实。这一切开始感觉有点笨拙。

另一个问题是,如果用户输入的不是整数,您的程序将产生未定义的行为(因为您实际上并没有初始化gradeA)。您可以测试是否scanf成功,因为它返回读取的项目数。

懒惰的方法是这样的:

if( 1 != scanf( "%d", &gradeA ) ) {
    printf( "Invalid input!"\n" );
    exit(1);
}

你可以决定。对于其余的答案,我会忽略这一点。

当你加强你的循环时,很明显代码重复是一个主题。您要更改的只是变量和提示。所以是时候把它变成一个函数了:

int grade_average( const char *what, int *total, float *average )
{
    int count = -1;
    int grade = 0;
    *total = 0;

    while( grade != -1 )
    {
        count++;
        *total += grade;

        printf( "Enter %s Grade, -1 to end: ", what );
        fflush(stdout);

        if( 1 != scanf("%d", &grade) ) return 0;  // fail on input error.
    }

    if( count > 0 ) {
        *average = (float)*total / count;
    }

    return 1;
}

现在你可以这样调用:

if( grade_average("Assignment", &totalA, &averageA) ) {
    printf( "Total is %.2f\n", averageA );
}

if( grade_average("Exam", &totalE, &averageE) ) {
    printf( "Total is %.2f\n", averageE );
}

if( grade_average("Quiz", &totalQ, &averageQ) ) {
    printf( "Total is %.2f\n", averageQ );
}
于 2013-02-13T22:41:52.840 回答