2016-11-30 97 views
0

我一直在嘗試從以前的帖子中找到我的同一問題的答案,但它不工作。下面是隻有幾個我檢查的鏈接:C編程:參數有不完整的類型錯誤

"parameter has incomplete type" warning C typedef: parameter has incomplete type How to resolve "parameter has incomplete type" error?

代碼:

#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) { 

} 

這裏是什麼結構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:改變ClientInfo itemClientInfo *item

#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 

錯誤:

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); 
+0

@kaylum剛剛在發佈之前加了幾秒鐘! :) – Jasmine

+1

「在另一個c文件」。這是行不通的。它需要在每個使用它的C文件中進行定義。直接或者在一個包含的頭文件中。 – kaylum

+0

或者該參數可能更改爲'ClientInfo * item'。 –

回答

2

typedef結構ClientInfo客戶端ClientInfo客戶端;

這是一個前向聲明 - 一個不完整類型的聲明,稍後將在client.c文件中完成。然而,這種在頭文件中使用前向聲明的設計使得結構的內容是私有的。

程序中沒有其他文件會知道結構包含的內容,也不能訪問成員。對於他們來說,結構仍然是不完整的,因此他們不能聲明這個結構類型的變量。但是他們可以聲明指向結構體的指針。

這實際上是如何在C中使用私有封裝的對象。這個概念被稱爲「不透明類型」,被認爲是很好的OO設計實踐。

解決問題的方法是更改​​「client.h」和「client.c」中的所有函數,以便它們可以用ClientInfo*指針代替。然後使用ClientInfo的其他文件將不得不使用指針。由於他們將無法聲明該類型的任何對象,因此必須提供構造函數(和析構函數)。例如:

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