为什么会出现这个错误:数组类型元素类型不完整、形参类型不完整?

问题描述 投票:0回答:1

我正在做一项作业,其中涉及使用 C 语言创建一个程序,以使用结构数组创建学生数据库。

以下是我的代码:

#include<stdio.h>

void accept(int no, struct student arr[20]); 
void display(int no, struct student arr[20]); 

struct student
    {
        char name [15];
        int rollno;
        float marks;
    };


int main()
{
    int no, n;
    
    printf("Enter the number of students: ");
    scanf("%d", &no);

    struct student arr[20];
    accept(no, arr);
    display(no, arr);
}

void accept(int no, struct student arr[20])
{
    for(int i=0; i<no; i++)
    {
        printf("Enter the name of the student: ");
        scanf("%s", &arr[i].name);
        printf("\nEnter the Roll No: ");
        scanf("%d", &arr[i].rollno);
        printf("\nEnter the marks: ");
        scanf("%f", &arr[i].marks);
    }
}

void display(int no, struct student arr[20])
{
    for(int i=0; i<no; i++)
    {
        printf("Name: %s ", arr[i].name);
        printf("Roll No: %d", arr[i].rollno);
        printf("Marks: %f", arr[i].marks);
        
    }
}

以下是我使用 gcc 在 cmd 上显示的错误:

ass3.c:5:36: error: array type has incomplete element type 'struct student'
 void accept(int no, struct student arr[20]);
                                    ^~~
ass3.c:5:28: warning: 'struct student' declared inside parameter list will not be visible outside of this definition or declaration
 void accept(int no, struct student arr[20]);
                            ^~~~~~~
ass3.c:6:37: error: array type has incomplete element type 'struct student'
 void display(int no, struct student arr[20]);
                                     ^~~
ass3.c:6:29: warning: 'struct student' declared inside parameter list will not be visible outside of this definition or declaration
 void display(int no, struct student arr[20]);
                             ^~~~~~~
ass3.c: In function 'main':
ass3.c:24:16: error: type of formal parameter 2 is incomplete
     accept(no, arr);
                ^~~
ass3.c:25:17: error: type of formal parameter 2 is incomplete
     display(no, arr);
                 ^~~
ass3.c:24: confused by earlier errors, bailing out

我无法理解是什么导致了这些错误。我该如何纠正它们?我在某处读到可以通过使用指针来解决这个问题。这是如何运作的?

c function compiler-errors structure
1个回答
1
投票

出现

void accept(int no, struct student arr[20]);
的地方,
struct student
之前尚未声明过。所以
struct student
是编译器第一次看到这个结构体标签。这充当标签的声明,并导致编译器创建一个名为
struct student
的新类型。

此时,编译器只知道类型存在。它不知道结构的成员是什么,因此也不知道结构的大小。这称为不完整类型。

struct student arr[20]
声明
arr
是这种类型的数组。 C 2018 6.7.6.2 1中有一条规则,数组的元素类型不能不完整。因此编译器会抱怨你的
struct student arr[20]
声明了一个元素类型不完整的数组。

因为这是参数声明,所以会自动调整为指针。你可以有一个指向不完整类型的指针;

struct student *arr
是允许的。但是,您的编译器会在应用自动调整之前应用有关数组元素类型的规则。

第二个问题是标签的范围。如上所述,该函数声明中的

struct student
声明了一个新的结构标记。该标签具有函数原型范围。它的作用域在函数声明的末尾结束。

当编译器稍后看到

struct student
的定义以及成员定义时,即处于新作用域中,并创建一个与旧实例分开的
struct student
的新实例。它是一种与早期类型不兼容的新类型。那么基本上不可能以符合 C 标准规则的有用方式来调用这个函数。由于第一个
struct student
的作用域已结束,因此函数的调用者无法创建可将其地址传递给函数的
struct student
。更糟糕的是,当定义函数时,该函数定义中的参数声明无法引用与原始函数声明相同的
struct student

要解决此问题,请将

struct student
的定义放在参数声明中使用它的任何函数的声明之前,而不是之后。然后,当编译器在参数声明中看到
struct student
时,它会将其视为对现有
struct student
类型的引用,而不是作为新类型的声明。

或者,您可以在函数声明之前声明

struct student;
。这将创建一个
struct student
类型,其标签具有文件范围。这解决了在函数声明内新创建类型的问题,但并没有解决不完整元素类型的问题。要解决这个问题,请将参数声明从
struct student arr[20]
更改为
struct student *arr

© www.soinside.com 2019 - 2024. All rights reserved.