2010-02-19 59 views
2

我剛開始使用C語言編寫模塊化編程。我想我對包含內容做了一些錯誤,因爲我收到了很多conflicting types for 'functionName'previous declaration of 'functionName' was here錯誤。我確實把保衛人員放在了位置上。在C中解釋模塊化編程的清晰教程?

您是否知道一個清楚的教程,解釋C語言中的模塊化編程,尤其是這些包含文件如何工作?


更新:我試圖孤立我的問題。根據要求,這是一些代碼。

更新2:更新代碼如下。錯誤也已更新。

/* 
* main.c 
*/ 
#include <stdio.h> 
#include "aStruct.h" 

int main() { 
    aStruct asTest = createStruct(); 

    return 0; 
} 

/* 
* aStruct.h 
*/ 
#ifndef ASTRUCT_H_ 
#define ASTRUCT_H_ 

struct aStruct { 
    int value1; 
    int value2; 
    struct smallerStruct ssTest; 
}; 
typedef struct aStruct aStruct; 

aStruct createStruct(); 

#endif /* ASTRUCT_H_ */ 

/* 
* smallerStruct.h 
*/ 
#ifndef SMALLERSTRUCT_H_ 
#define SMALLERSTRUCT_H_ 

struct smallerStruct { 
    int value3; 
}; 
typedef struct smallerStruct smallerStruct; 

smallerStruct createSmallerStruct(); 

#endif /* SMALLERSTRUCT_H_ */ 

/* 
* aStruct.c 
*/ 
#include <stdio.h> 
#include "smallerStruct.h" 
#include "aStruct.h" 

aStruct createStruct() { 
    aStruct asOutput; 

    printf("This makes sure that this code depends on stdio.h, just to make sure I know where the inclusion directive should go (main.c or aStruct.c).\n"); 

    asOutput.value1 = 5; 
    asOutput.value2 = 5; 
    asOutput.ssTest = createSmallerStruct(); 

    return asOutput; 
} 

/* 
* smallerStruct.c 
*/ 
#include <stdio.h> 
#include "smallerStruct.h" 

smallerStruct createSmallerStruct() { 
    smallerStruct ssOutput; 
    ssOutput.value3 = 41; 
    return ssOutput; 
} 

這會產生以下錯誤消息:

At aStruct.h:10

  • field 'ssTest' has incomplete type

At main.c:8

  • unused variable `asTest' (this one makes sense)
+1

你可以發佈一個代碼給你帶來麻煩嗎? – FrustratedWithFormsDesigner 2010-02-19 14:26:51

+0

我按要求添加了一個樣本。 – Pieter 2010-02-19 16:29:44

+1

你需要在astruct.h中#include「smallerStruct.h」 – 2010-02-20 10:54:24

回答

2

多重定義問題很可能來自您包含代碼的方式。您使用#include「aStruct.c」而不是#include「aStruct.h」。除了#include之外,我懷疑你還將.c文件編譯到你的項目中。這會導致編譯器由於同一個函數的多個定義而變得混亂。

如果將#include更改爲#include「aStruct.h」,並確保將三個源文件編譯並鏈接在一起,則錯誤應該消失。

+0

對不起,沒有運氣。在aStruct.h:10('struct smallerStruct ssTest;'),我得到以下錯誤:'field'ssTest'具有不完整的類型'。爲什麼我應該#include .h文件而不是.c文件? .c文件#包含.h文件,但不是其他方式。所以.c文件不會在任何地方被提及,如果我只#include它的.h對應。 – Pieter 2010-02-20 10:26:29

+0

爲了您的方便,我更新了頁面頂部的代碼。 – Pieter 2010-02-20 10:38:16

+0

不應在源代碼中提及.c文件,而應在Makefile中提及.c文件。 – mouviciel 2010-02-20 11:02:16

3

包容的基礎是確保你的頭只包含一次。這通常是這樣一個序列進行:

/* header.h */ 
#ifndef header_h_ 
#define header_h_ 

/* Your code here ... */ 

#endif /* header_h_ */ 

第二點是通過用前綴處理手動僞命名空間來照顧可能名稱衝突。

然後在你的頭文件中只提供public API的函數聲明。這可能意味着添加typedefs和枚舉。儘可能避免包含常量和變量聲明:更喜歡訪問函數。

另一個規則是從不包含.c文件,只有.h。這就是模塊化的要點:一個依賴於另一個模塊的給定模塊只需要知道它的接口,而不是它的實現。

A對於您的具體問題,aStruct.h使用struct smallerStruct,但對此一無所知,尤其是其能夠分配aStruct變量的大小。 aStruct.h需要包括smallerStruct.h。包括smallerStruct.h之前aStruct.hmain.c編譯aStruct.c時不解決問題。

+0

我的確記得包括保安人員。 – Pieter 2010-02-19 14:28:26

+0

只是要小心,不要把這個複製粘貼到你的代碼中。確保_header_被重命名爲與頭部名稱相似的內容。 – 2010-02-19 14:28:51

+2

另外,作爲包含警衛(或任何標識符)的第一個字符是否具有下劃線不調皮?這些標識符是保留的,不是嗎?我總是使用「FILENAME_H_」 - 尾部下劃線是合法的。 – Steve314 2010-02-19 14:37:40

0

這樣的錯誤意味着函數聲明(返回類型或參數計數/類型)與其他函數聲明或函數定義不同。

previous declaration消息指向衝突聲明。

+0

他們完全一樣。我確保在實際功能之前將原型包含在標題中。 – Pieter 2010-02-19 15:14:56

+0

如果您不包含標題,該怎麼辦? – qrdl 2010-02-19 16:07:42