C中函数声明的编译错误

Compilation error in function declaration in C

我在编译这个 C 程序的过程中遇到了与函数声明有关的错误。这里有什么问题?当我声明 void display(student); 时它会显示警告,但如果我更改为 void display(struct student st) 它会显示一些错误。

#include<stdio.h>
void display(student);
void read_student(student);
struct student{
    int roll;
    char name[20],depart[20],sex,result;

    float percent,marks[5],total; 

};

void main(){
    int n;
    printf("enter the no of data you want to enter ??");
    scanf("%d",&n);

     struct student s[n];
     for(int i=0;i<n;i++)
        read_student(&s[i]);
        printf("\n---------------------------------------------------Result Sheet --------------------------------------------------------------------");
        printf("\nRoll No.\tName\t\tSex\tDepartment\t\tMarks\t\t\t\tTotal\tPercentage\tResult ");
    printf("\n----------------------------------------------------------------------------------------------------------------------------------------");
    printf("\n                              \t\t\t\tA\tB\tC\tD\tE\n");
    printf("----------------------------------------------------------------------------------------------------------------------------------------");

     for(int i=0;i<n;i++)  
        display(s[i]);


}
 void display(struct student st){


    printf("\n%2d\t%10s\t\t%c\t%10s\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%4.2f\t  %2.2f\t\t%c\n",st.roll,st.name,st.sex,st.depart,st.marks[0],st.marks[1],st.marks[2],st.marks[3],st.marks[4],st.total,st.percent,st.result);


}
 void read_student(struct student *std){
     int c=0,i;
    printf("Enter the roll no:");
    scanf("%d",&std->roll);
     printf("enter the name:\n");
     scanf("%s",std->name);
     printf("enter Sex:\n");
     scanf(" %c",&std->sex);
     printf("Enter the department:\n");
     scanf("%s",std->depart);
     printf("enter the marks in 5 subjects:\n");
     for(i=0;i<5;i++){
      scanf("%f",&std->marks[i]);
      std->total=std->total+std->marks[i];
      if(std->marks[i]>=40)
      c++;
     }
      if(c==5)
      std->result='p';
      else
        std->result='f';



     std->percent=(std->total/500)*100;


}

当在代码的其他地方使用它时,编译器需要知道 struct student 是什么,例如将一个函数声明为 argument/parameter 类型。编译器从上到下读取源文件。在将结构用作函数声明中的类型之前,需要先声明该结构:

struct student;   // forward declaration of structure `student`.

void display(struct student);       // ok, because `struct student` is declared before.
void read_student(struct student*); // ok, because `struct student` is declared before.

struct student{                     // definition of structure `student`.
    int roll;
    char name[20],depart[20],sex,result;
    float percent,marks[5],total; 
};

或者,您可以在函数声明之前定义结构:

struct student{    // define the structure `student` before the function declarations.
    int roll;
    char name[20],depart[20],sex,result;
    float percent,marks[5],total; 
};

void display(struct student);
void read_student(struct student*);

另一种方法是将函数 read_studentdisplay 的定义放在 main() 之前,但在结构 student 的定义之后。通过这种方式,您可以省略函数 read_studentdisplay 的单独声明,当然还有结构 student 的前向声明:

#include<stdio.h>

struct student{
    int roll;
    char name[20],depart[20],sex,result;
    float percent,marks[5],total; 
};

void read_student(struct student *std){
     int c=0,i;
     printf("Enter the roll no:");
     scanf("%d",&std->roll);
     printf("enter the name:\n");
     scanf("%s",std->name);
     printf("enter Sex:\n");
     scanf(" %c",&std->sex);
     printf("Enter the department:\n");
     scanf("%s",std->depart);
     printf("enter the marks in 5 subjects:\n");
     for(i=0;i<5;i++){
      scanf("%f",&std->marks[i]);
      std->total=std->total+std->marks[i];
      if(std->marks[i]>=40)
      c++;
     }
      if(c==5)
      std->result='p';
      else
        std->result='f';

     std->percent=(std->total/500)*100;
}

void display(struct student st){
    printf("\n%2d\t%10s\t\t%c\t%10s\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%4.2f\t  %2.2f\t\t%c\n",st.roll,st.name,st.sex,st.depart,st.marks[0],st.marks[1],st.marks[2],st.marks[3],st.marks[4],st.total,st.percent,st.result);
}

int main(){
    int n;
    printf("enter the no of data you want to enter ??");
    scanf("%d",&n);

    struct student s[n];

    for(int i=0;i<n;i++)
        read_student(&s[i]);

    printf("\n---------------------------------------------------Result Sheet --------------------------------------------------------------------");
    printf("\nRoll No.\tName\t\tSex\tDepartment\t\tMarks\t\t\t\tTotal\tPercentage\tResult ");
    printf("\n----------------------------------------------------------------------------------------------------------------------------------------");
    printf("\n                              \t\t\t\tA\tB\tC\tD\tE\n");
    printf("----------------------------------------------------------------------------------------------------------------------------------------");

    for(int i=0;i<n;i++)  
        display(s[i]);
}

在函数声明中可以省略参数标识符,但不能省略参数类型。

也不允许使用结构 student 而不在 struct 关键字之前,因为您尝试过:

void display(student);

由于您根据其定义使用结构 student

struct student{
...
};

如果您使用 typedef,例如:

typedef struct student{
...
} student;

您可以省略 struct 关键字,但如果您使用 typedef 或仅按原样使用结构,这在社区中是一个关于可读性的争议话题。所有对此的引用,您可以在这些问题的答案中看到:

typedef struct vs struct definitions

Why should we typedef a struct so often in C?

我个人建议继续使用 struct 变体,即使它需要更多的按键输入,但会让您的代码更清晰一些。