【问题标题】:using scanf in pointers to integer array在指向整数数组的指针中使用 scanf
【发布时间】:2013-08-22 10:47:37
【问题描述】:

这个程序应该存储输入的 3 名学生的成绩并打印平均成绩。但是,如果我要求学生 B 的平均值,它会打印学生 A 的平均值。学生 A 的平均值为 0。我似乎找不到哪里出错了。请帮忙 例如Student_A = {7,7,7},Student_B = {8,8,8}; ave(Student_B) = 7

#include<stdio.h>

int i;
char j;
int student_A[4];
int student_B[4];
int student_C[4];
float grade_input(int student[]);
float ave(int student[]);

main(){
    printf("For Student A:\n");
    grade_input(&student_A[4]);
    printf("For Student B:\n");
    grade_input(&student_B[4]);
    printf("For Student C:\n");
    grade_input(&student_C[4]);
    do{
        printf("Whose average grade do you want to see, a ,b ,c?  ");
        getchar();
        scanf("%c", &j);

        if(j=='a'){
            printf("%.2f\n", ave(student_A));
        }
        if(j=='b'){
            printf("%.2f\n", ave(student_B));
        }
        if(j=='c'){
            printf("%.2f\n", ave(student_C));
        }
    }while(j=='a' || j=='b' || j=='c');
}

float grade_input(int student[]){
    int i;
    for(i=0; i<3; i++){
        printf("Enter grade %d: ", i+1);
        scanf("%d", &student[i]);
    }
}

float ave(int student[]){
    return (student[0] + student[1] + student[2])/3.0;
}

【问题讨论】:

  • 您的问题是通过引用 4 元素数组的元素 4 进行越界访问; 请参阅下面的详细答案。这个问题根本与 scanf() 无关。 scanf 做得很好,你给它一个不好的使用指针。
  • 关于在使用接受的答案后可能仍然存在的潜在输入问题:将scanf("%c", &amp;j); 替换为scanf(" %c", &amp;j);(额外的空格)。这将消耗任何以前的\n

标签: c scanf


【解决方案1】:

您遇到的问题是将&amp;student_X[4] 传递给grade_input()。这完全是非法的,因为它是一个 4 元素数组;未定义访问带有下标 4 的元素。由于它们是连续定义的,因此当您使用 &amp;student_A[4] 调用 grade_input() 函数时,您最终会有效地将指针发送到 student_B,而这正是您所看到的!

您应该将指针传递给数组。我在下面稍微重写了您的代码以进行说明。

#include<stdio.h>

int i;
char j;
int student_A[4];

/* ******* */
/* note that student_A is defined as a 4 element array */

int student_B[4];
int student_C[4];
float grade_input(int student[]);
float ave(int student[]);

main(){
  printf("For Student A:\n");

  /* ******* */
  /* note that student_A is defined as a 4 element array */
  /* a pointer to the array is just student_A, not &student_A[4] */
  grade_input(student_A);
  printf("For Student B:\n");
  grade_input(student_B);
  printf("For Student C:\n");
  grade_input(student_C);
  do{
    printf("Whose average grade do you want to see, a ,b ,c?  ");
    scanf("%c", &j);

    if(j=='a'){
      printf("%.2f\n", ave(student_A));
    }
    else if(j=='b'){
      printf("%.2f\n", ave(student_B));
    }
    else if(j=='c'){
      printf("%.2f\n", ave(student_C));
    }
    else
      printf ( "Enter a, b or c\n" );

  }while(j != 'q');
}

float grade_input(int student[]){
  int i;
  for(i=0; i<3; i++){
    printf("Enter grade %d: ", i+1);
    scanf("%d", &student[i]);
  }
}

float ave(int student[]){
  return (student[0] + student[1] + student[2])/3.0;
}

【讨论】:

    【解决方案2】:

    scanf("%c", &amp;j); 之前不需要做getchar(); 无论你应该用fflush(stdout); 清理缓冲区还是这样做

    char c;
    while ((c = getchar()) != '\n');
    

    所以你的完整代码应该是这样的:

    #include<stdio.h>
    
    int i;
    char j;
    int student_A[4];
    int student_B[4];
    int student_C[4];
    float grade_input(int student[]);
    float ave(int student[]);
    
    main(){
        printf("For Student A:\n");
        grade_input(&student_A[4]);
        printf("For Student B:\n");
        grade_input(&student_B[4]);
        printf("For Student C:\n");
        grade_input(&student_C[4]);
        do{
            printf("Whose average grade do you want to see, a ,b ,c?  ");
            fflush(stdout); // THE CHANGE
            scanf("%c", &j);
    
            if(j=='a'){
                printf("%.2f\n", ave(student_A));
            }
            if(j=='b'){
                printf("%.2f\n", ave(student_B));
            }
            if(j=='c'){
                printf("%.2f\n", ave(student_C));
            }
        }while(j=='a' || j=='b' || j=='c');
    }
    
    float grade_input(int student[]){
        int i;
        for(i=0; i<3; i++){
            printf("Enter grade %d: ", i+1);
            scanf("%d", &student[i]);
        }
    }
    
    float ave(int student[]){
        return (student[0] + student[1] + student[2])/3.0;
    }
    

    【讨论】:

    • 问题依然存在。 :/ 如果我选择查看学生 B 的成绩,它会打印学生 A 的 ave
    • @JohnNoelMaape 你怎么知道这是大街?
    • 如果我把 A 的 3 个 7 和 B 的 3 个 8 去掉,当我要求 B 的平均值时,我得到 7
    • @JohnNoelMaape 我已经测试并得到了正确的结果......我真的不知道出了什么问题,你确定这不是输入吗?当您询问 B 的平均值时,您是输入“B”还是“b”?
    • 我输入小字符。所以我输入“b”
    猜你喜欢
    • 1970-01-01
    • 2012-01-24
    • 1970-01-01
    • 2019-10-27
    • 2017-02-12
    • 2021-01-10
    • 2017-07-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多