2009-03-23 17 views
25

मैं एक सी नौसिखिया हूं और मैं कोड :: ब्लॉक के साथ एक कंसोल एप्लिकेशन लिखने की कोशिश कर रहा था। यहाँ (सरलीकृत) कोड है: main.c:सी में कई परिभाषाओं को कैसे रोकें?

#include <stdio.h> 
#include <stdlib.h> 
#include "test.c" // include not necessary for error in Code::Blocks 

int main() 
{ 
    //t = test(); // calling of method also not necessary 
    return 0; 
} 

test.c:

void test() {} 

जब मैं इस कार्यक्रम बनाने की कोशिश है, यह देता है निम्न त्रुटियों:

 
*path*\test.c|1|multiple definition of `_ test'| 
obj\Debug\main.o:*path*\test.c|1|first defined here| 

कोई तरीका नहीं है कि मैं परीक्षण को परिभाषित कर रहा हूं (हालांकि मुझे नहीं पता कि अंडरस्कोर कहां से आ रहा है) और ऐसा लगता है कि परिभाषा किसी भी तरह से दो बार शामिल है। यह सब कोड है।

मैंने यह अस्वीकार कर दिया है कि यह त्रुटि अन्य कार्यों या फ़ाइलों को परीक्षण या test.c. कहलाते हुए कुछ नामकरण संघर्ष के कारण है। ध्यान दें कि एकाधिक और पहली परिभाषा एक ही फ़ाइल में एक ही पंक्ति में हैं।

क्या किसी को पता है कि इसका क्या कारण है और मैं इसके बारे में क्या कर सकता हूं? धन्यवाद!

उत्तर

66

तुम वास्तव में दो बार test.c के स्रोत कोड संकलन:

  • पहली बार जब test.c ही संकलन,
  • दूसरी बार जब main.c जो सभी test.c स्रोत शामिल संकलन।

क्या आप test() समारोह का उपयोग करने के अपने main.c में जरूरत है एक सरल घोषणा, नहीं इसकी परिभाषा है।

void test(void); 

इस संकलक इनपुट पैरामीटर और वापसी प्रकार के साथ इस तरह के एक समारोह में मौजूद है कि सूचित: यह जो कुछ होता है एक test.h हेडर फाइल को शामिल करके हासिल की है। यह फ़ंक्शन क्या करता है ({ और } के अंदर सबकुछ) आपके test.c फ़ाइल में छोड़ा गया है।

मुख्य.c में, #include "test.c"#include "test.h" द्वारा प्रतिस्थापित करें।

एक अंतिम बिंदु: आपके कार्यक्रम अधिक जटिल होने के साथ, आपको उन स्थितियों का सामना करना पड़ेगा जब हेडर फ़ाइलों को कई बार शामिल किया जा सकता है।

#ifndef TEST_H_INCLUDED 
#define TEST_H_INCLUDED 

void test(void); 

#endif 
+0

_TEST.H_ जैसे नाम अंडरस्कोर से शुरू होते हैं और पूंजी पत्र सी उपयोगकर्ता कोड में अवैध होते हैं - वे कंपाइलर कार्यान्वयनकर्ताओं के लिए आरक्षित हैं। –

+0

आपको हेडर फ़ाइल में परीक्षण() को पैरामीटर के बारे में जानकारी प्रदान करनी चाहिए, यानी शून्य परीक्षण(); -> शून्य परीक्षण (शून्य); – aib

+0

मैंने अभी प्रश्न में सुझाए गए इंटरफेस को लिया है, लेकिन आप सही हैं: मैं अपना जवाब अपडेट करता हूं। • पहली बार जब test.c • दूसरी बार ही संकलन, जब main.c वाले हैं, जिसमें test.c source.' और संकलन: – mouviciel

9

आपको .c फ़ाइलों में अन्य स्रोत फ़ाइलों (* .c) शामिल नहीं करना चाहिए। मुझे लगता है कि आप एक शीर्षलेख ( .h) फ़ाइल टेस्ट फ़ंक्शन के DECLARATION के साथ फ़ाइल करना चाहते हैं, और यह एक अलग .c फ़ाइल में परिभाषा है।

त्रुटि परीक्षण समारोह की कई परिभाषाएं (test.c में एक और main.c में अन्य)

4

कार्यान्वयन फ़ाइल (test.c) यह कारण बनता है भी शामिल है के कारण होता है अपने main.c के लिए prepended किया जाना है और वहां और फिर अलग से पालन किया। तो, फ़ंक्शन test में दो परिभाषाएं हैं - main.c के ऑब्जेक्ट कोड में और एक बार test.c में, जो आपको ओडीआर उल्लंघन देता है। के माध्यम से एक बार - आप अपने कोड :: ब्लाकों परियोजना के लिए test.c जोड़ा है, तो परिभाषा दो बार देखा जाएगा

/* test.h */ 
#ifndef TEST_H 
#define TEST_H 
void test(); /* declaration */ 
#endif /* TEST_H */ 
4

: आप main.c में एक हैडर test की घोषणा युक्त फ़ाइल बनाने के लिए की जरूरत है और शामिल हैं यह # शामिल करें और एक बार लिंकर द्वारा। आप की जरूरत है:

  • #include "test.c"
  • एक फ़ाइल test.h जो घोषणा-पत्र शामिल बनाने निकालें: शून्य परीक्षण();
  • main.c

20

अंडरस्कोर संकलक द्वारा वहां डाल दिया और लिंकर द्वारा प्रयोग किया जाता है में फ़ाइल test.h शामिल हैं। मूल पथ है:

void test(void); 

इस संकलक करने देता है:

main.c 
test.h ---> [compiler] ---> main.o --+ 
            | 
test.c ---> [compiler] ---> test.o --+--> [linker] ---> main.exe 

तो, अपने मुख्य कार्यक्रम है जो केवल इस तरह के समारोह प्रोटोटाइप के रूप में घोषणाओं, होनी चाहिए परीक्षण मॉड्यूल के लिए हेडर फाइल को शामिल करना चाहिए पता है कि यह तब मौजूद है जब main.c संकलित किया जा रहा है लेकिन वास्तविक कोड test.c में है, फिर test.o.

यह लिंकिंग चरण है जो दो मॉड्यूल को एक साथ जोड़ता है।

main.c में test.c सहित, आप main.o में test() फ़ंक्शन को परिभाषित कर रहे हैं। संभवतः, आप मुख्य.o और test.o को जोड़ रहे हैं, जिनमें से दोनों में फ़ंक्शन टेस्ट() शामिल है।

+1

ऊपर वोट अच्छा चित्र के लिए मदद करता है। –

+1

अच्छा ASCII कला आरेख के लिए एक और अप-वोट। –

4

आप एक ही बात को प्राप्त करने के headerfile के शीर्ष पर दृश्य स्टूडियो उपयोग कर रहे हैं तो आप भी कर सकता है "#pragma एक बार": इसे रोकने के लिए, शीर्ष लेख सूत्रों कभी कभी विशिष्ट मैक्रो परिभाषाओं से, जैसे संलग्न हैं "#ifndef ..." के रूप में - लपेटना। कुछ अन्य कंपाइलर्स शायद इसका भी समर्थन करते हैं .. .. हालांकि, ऐसा न करें: डी क्रॉस-कंपाइलर संगतता प्राप्त करने के लिए # ifndef-wrapping के साथ चिपकाएं। मैं सिर्फ आपको यह बताने के लिए चाहता था कि आप एक बार #pragma भी कर सकते हैं, क्योंकि आप शायद अन्य लोगों के कोड को पढ़ने के दौरान इस कथन को पूरा करेंगे।

यह

5

साथ गुड लक मैं इसी तरह की समस्या थी और मैं जिस तरह से निम्नलिखित इसे हल। इस प्रकार

का समाधान:

समारोह प्रोटोटाइप घोषणाओं और वैश्विक चर test.h फ़ाइल में होना चाहिए और आप हेडर फाइल में वैश्विक चर प्रारंभ नहीं कर सकते हैं।

समारोह परिभाषा और test.c फ़ाइल में वैश्विक चर के उपयोग

यदि आप शीर्षक में वैश्विक चर प्रारंभ यह निम्नलिखित होगा त्रुटि

`_ परीक्षण 'के कई परिभाषा | obj \ Debug \ main.o: पथ \ test.c | 1 | पहले यहां परिभाषित किया गया |

हेडर फ़ाइल में प्रारंभिक वैरिएबल की बस घोषणाएं प्रारंभिकरण को काम नहीं करना चाहिए।

आशा है कि यह

चीयर्स

संबंधित मुद्दे