【问题标题】:C Programming: parameter has incomplete type errorC编程:参数有不完整的类型错误
【发布时间】:2017-04-14 08:07:02
【问题描述】:

我一直在尝试从我以前的帖子中找到相同问题的答案,但没有成功。以下是我检查过的几个链接:

代码:

#include "listADT.h"
#include "client.h"
#include <stdlib.h>
#include <stdio.h>


struct node {
   ClientInfo *data; // added pointer here
   struct node * next;
};

struct list_type {
   struct node * front;
   int size;
};

ListType create() {

    ListType listptr = malloc(sizeof(struct list_type));

    if (listptr != NULL) {
        listptr->front = NULL;
        listptr->size = 0;
    }
    return listptr;
}



void push(ListType listptr, ClientInfo item) {  <--- error here

   struct node *temp = malloc(sizeof(struct node));

   if (temp != NULL) {
       temp->data = item;
       temp->next = listptr->front;
       listptr->front = temp;
       (listptr->size)++;
   }
}

int is_empty(ListType l) {
    return l->size == 0;
}

int size_is(ListType l) {
    return l->size;
}

void make_empty(ListType listptr) {

    struct node* current = listptr->front;

    while (current->next != NULL) {
        destroy(listptr);
        current = current->next;        
    }

    (listptr->size)--;

}

void destroy(ListType listptr) {
    struct node *temp = malloc(sizeof(struct node));
    temp = listptr->front;
    listptr->front = listptr->front->next;

    free(temp); 
    (listptr->size)--;
}

void delete(ListType listptr, ClientInfo item) { <--- error here
    struct node* current = listptr->front;
    struct node *temp = malloc(sizeof(struct node));

    while (current-> data != item) {
        temp = current;
        current = current->next;        
    }

    temp->next = current->next;
    (listptr->size)--;
}

int is_full(ListType l) {

}

下面是 struct ClientInfo 包含在另一个 c 文件中的内容:

typedef struct ClientInfo {
    char id[5];
    char name[30];
    char email[30];
    char phoneNum[15];
} ClientInfo;

这是我得到的错误:

listADT.c:41:40: error: parameter 2 (‘item’) has incomplete type
void push(ListType listptr, ClientInfo item) {
                                    ^
listADT.c:83:42: error: parameter 2 (‘item’) has incomplete type
void delete(ListType listptr, ClientInfo item) {

我现在完全不知道如何解决它。如果我需要包含任何其他信息,请告诉我。

编辑部分 |

listADT.h:

#ifndef LISTADT_H
#define LISTADT_H

typedef struct list_type *ListType;
typedef struct ClientInfo ClientInfo;

ListType create(void);
void destroy(ListType listP);
void make_empty(ListType listP);
int is_empty(ListType listP);
int is_full(ListType listP);
void push(ListType listP, ClientInfo item);
void delete(ListType listP, ClientInfo item);
void printl(ListType listP);

#endif

ClientInfo item 更改为ClientInfo *item 后出错:

listADT.h:12:6: note: expected ‘ClientInfo * {aka struct ClientInfo *}’ 
but argument is of type ‘ClientInfo {aka struct ClientInfo}’
void push(ListType listP, ClientInfo *item);

【问题讨论】:

  • “在另一个 c 文件中”。那是行不通的。它需要在每个使用它的 C 文件中定义。直接或在包含的头文件中。
  • 或者参数可以改成ClientInfo *item
  • @kaylum 在我的作业中指出“结构定义和操作可以写在单独的 .h 和 .c 文件中,也可以驻留在 client.h 和 client.c 中”
  • @KenY-N 我这样做时出错了
  • 您当然还需要更改调用这些函数的位置以传入指针而不是结构。

标签: c


【解决方案1】:

typedef struct ClientInfo ClientInfo;

这是一个前向声明 - 一个不完整类型的声明,稍后将在您的 client.c 文件中完成。但是,这种在头文件中带有前向声明的设计使结构的内容成为私有的。

您的程序中没有其他文件会知道该结构包含什么,也无法访问成员。对于他们来说,结构仍然是不完整的,因此他们不能声明这种结构类型的变量。但是,它们可以声明指向结构的指针。

这实际上是您在 C 中对对象进行私有封装的方式。这个概念称为“不透明类型”,被认为是良好的 OO 设计实践。

您可以做些什么来解决这些问题,即更改“client.h”和“client.c”中的所有函数,以便它们可以使用ClientInfo* 指针。然后使用ClientInfo 的所有其他文件都必须使用指针。由于他们无法声明该类型的任何对象,因此您必须提供构造函数(和析构函数)。例如:

ClientInfo* client_create (void)
{
  return malloc(sizeof(ClientInfo));
}

【讨论】:

    猜你喜欢
    • 2014-01-31
    • 2012-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-20
    • 2019-05-16
    相关资源
    最近更新 更多