2011-11-29 6 views
11

मेरे पास एक एएनएसआई सी प्रोग्राम है जिसमें दो फाइलें शामिल हैं। पहली फ़ाइल में main() फ़ंक्शन शामिल है, और दूसरी फ़ाइल में अन्य फ़ंक्शन हैं जो पहली फ़ाइल कॉल करते हैं। इससे पहले कि main() समारोह परिभाषा, मैं निम्नलिखित कोड डाला है:सी प्रोग्राम में वैश्विक स्थिर (एकाधिक फ़ाइलों में काम) कैसे करें?

#define PI 3.14159265358979323846 

लेकिन 2 फ़ाइल इस चर नहीं देखा। पहली फ़ाइल इसे ठीक देखती है। फिर, मैंने फ़ंक्शन परिभाषाओं से पहले, दूसरी फ़ाइल में इसे उसी फ़ाइल में रखा है (इसे ऊपर की पहली फ़ाइल में रखते हुए), लेकिन फिर भी दूसरी फ़ाइल इसे नहीं देखती है। हालात हमेशा ठीक संकलित करते हैं, लेकिन जब यह gdb में परिवर्तनीय पीआई का पता लगाता है, तो यह "No symbol "PI" in current context."

पीआई को एप्लिकेशन में संकलित सभी फ़ाइलों में वैश्विक निरंतर देखने योग्य बनाने के लिए कैसे दिखाता है?

संपादित करें/अद्यतन:

प्रतिक्रिया अब तक, मैं निम्न फ़ाइल बना लिया है के आधार पर:

myheader.h

#ifndef my_header_stuff 
#define my_header_stuff 
    #define PI 3.1415926535897932384626433832795 
#endif 

और दो फ़ाइलों मैं चाहता हूँ में इस निरंतर पीआई को देखने के लिए, मैंने इस फ़ाइल को निम्नानुसार शामिल किया है:

file1.c

#include <stdio.h> 
#include <stdlib.h> 
#include "myheader.h" 
int main(void) { 
    etc... 
} 

और file2.c

#include <stdio.h> 
#include <stdlib.h> 
#include "myheader.h" 
double interesting_function(void) { 
    etc... 
} 

सवाल:

  1. जब मैं डिबग करने के लिए GDB का उपयोग करें, b PI रिटर्न (दोनों फ़ाइलों में, एक ही परिणाम) "कोई प्रतीक वर्तमान संदर्भ में "पीआई" "। हालांकि, पीआई के आधार पर गणित की गणना सही ढंग से की जाती है। जीडीबी में पीआई देखने का कोई तरीका है?

  2. क्या मैं myheader.h फ़ाइल में stdio और stdlib के लिए दो पंक्तियां भी शामिल कर सकता हूं?

  3. क्या मैं myheader.h फ़ाइल में कोई फ़ंक्शन प्रोटोटाइप भी शामिल कर सकता हूं? अगर मैं करता हूं, और फिर मान लें कि मैं एक फ़ाइल 3.c बना रहा हूं जिसमें इन प्रोटोटाइपों में से किसी की आवश्यकता नहीं है क्योंकि यह उन कार्यों का उपयोग नहीं करता है, क्या कोई नुकसान हुआ है?

+0

हमेशा .h फ़ाइलों में सभी परिभाषाओं को .c फ़ाइलों और घोषणाओं (मैक्रोज़ सहित) में डाल दें।उस समय 99% समस्या को हल करना चाहिए। – JosephH

+0

धन्यवाद जोसेफ एच, क्या आप इस के यांत्रिकी के साथ मेरी मदद कर सकते हैं? ऊपर मेरा प्रयास देखें। – ggkmath

+0

क्या उत्तर मैंने अभी पोस्ट किया है – JosephH

उत्तर

3
  1. यह सामान्य है कि जीडीबी में एक मैक्रो परिभाषा दिखाई नहीं दे रही है। ऐसा इसलिए है क्योंकि जीसीसी वास्तविक पीआई मान के साथ प्रत्येक PI को प्रतिस्थापित करता है।
  2. हां। आपके मामले में, यह चोट नहीं पहुंचाता है। यदि .h फ़ाइल में प्रोटोटाइप होता है (उन्हें आमतौर पर घोषणाएं कहा जाता है) जो किसी अन्य प्रकार में परिभाषित किए गए प्रकार का उपयोग करता है, तो आप अपने हेडर फाइलों में #include
  3. हां कर सकते हैं। आप घोषित कर सकते हैं कि आप कभी भी प्रोटोटाइप का काम करते हैं और यह आपके प्रोग्राम की कार्यक्षमता के मामले में कोई नुकसान नहीं करेगा। कंपाइलर उन कार्यों की परिभाषाओं के अस्तित्व की जांच भी नहीं करेगा जबतक कि आप वास्तव में उन्हें कहीं और कहें।
+0

धन्यवाद जोसेफ एच !!! एक और सवाल ... मैंने मूल रूप से प्रत्येक फ़ाइल में #define रखा है, जो file1.c में ठीक काम करने लग रहा था, लेकिन file2.c नहीं (कोई संकलन त्रुटियां नहीं, लेकिन गणित ने गलत तरीके से गलत परिणाम दिया)। #include का उपयोग करना फ़ाइल में कट-एंड-पेस्ट सामग्री की तरह है, है ना? Myheader.h दृष्टिकोण अलग-अलग नतीजों का उत्पादन क्यों करता है - क्या दोनों समाधान सिर्फ 'NAME नाम निर्धारित करें' पर निर्भर नहीं हैं? या, यदि आप इसे समझा नहीं सकते हैं, तो शायद यह मेरा डिबगिंग भ्रम था। – ggkmath

+0

मुझे नहीं लगता कि आपको अलग-अलग परिणाम मिलेंगे। क्या आप दोबारा जांच सकते हैं? – JosephH

2

मैं हेडर फाइल में पीआई घोषित करने और सभी स्रोत फ़ाइलों को यह हेडर फाइल में शामिल था

आप समारोह घोषणाओं, अपने हेडर फाइल में मैक्रो (और शायद कुछ सरल इनलाइन कार्यों) से देना चाहिए कार्यान्वयन ग फ़ाइलों

में रखा जाना चाहिए // मैं अपनी टिप्पणी

+0

क्या सभी फ़ाइलों से फ़ंक्शन प्रोटोटाइप सभी को हेडर फ़ाइल में भी रखा जाना चाहिए? मैंने ऐसा करना शुरू कर दिया, फिर इसे छोड़ दिया जब मुझे अनुभव हुआ कि किसी विशेष फ़ाइल में नहीं जाने वाले फ़ंक्शंस में उनके प्रोटोटाइप होने की आवश्यकता नहीं है, और फिर मुझे आश्चर्य हुआ कि अगर यह अनावश्यकता हो तो कुछ तोड़ सकता है या अक्षम हो सकता है। – ggkmath

+0

मैंने अपना उत्तर –

+0

धन्यवाद जनवरी संपादित किया। क्या आप शीर्षलेख में घोषित करने के लिए # परिभाषित पीआई 3.1415 9 का उपयोग करेंगे? यदि ऐसा नहीं है तो #include बस इसे सम्मिलित करें जैसा कि मेरे पास वर्तमान में है? यदि नहीं, तो कैसे? – ggkmath

1

आप एक वैश्विक चर बना सकते हैं के जवाब का जवाब संपादित।

//file1.c 
int my_global; 


//file2.c 
extern int my_global; 
//code using my_global... 

ध्यान दें कि प्रीप्रोसेसर का उपयोग अधिकतर निराश होता है।

यह भी ध्यान रखें कि अन्य द्वारा सुझाए गए एमएफआई परिभाषित नवीनतम सी मानक (सी 99) में उपलब्ध नहीं है, इसलिए आप इस पर भरोसा नहीं कर सकते हैं।

+0

ऊपर लिखा है, पीआई के मूल्य के लिए? –

+0

क्या ये दोनों फ़ंक्शन परिभाषाओं से पहले रखे गए हैं? – ggkmath

+0

@ggkmath हां, यदि आप चाहते हैं कि * my_global * उन कार्यों द्वारा उपयोग किया जाए। – Beginner

2

एक मैक्रो एक चर नहीं है, और यह एक चर के रूप में gdb में प्रकट नहीं होगा। चीजें ठीक संकलित कर रही हैं क्योंकि वे ठीक काम कर रहे हैं; आपके पास जीडीबी के लिए गलत उम्मीदें हैं।

सामान्यतः, एक से अधिक स्थानों में आवश्यक एक मैक्रो को हेडर फ़ाइल में परिभाषित किया जाना चाहिए जिसमें हर जगह शामिल है; उदाहरण के लिए, मैक्रो M_PI मानक में पीआई होने के लिए पहले ही परिभाषित किया गया है जिसमें math.h शामिल है।

अन्य बात यह है कि आप कर सकते हैं एक फ़ाइल और दूसरों के सभी में extern const int PI; में const int PI = 3.14159etcetc; के लिए है, लेकिन यह एक दर्द है, क्योंकि यह मूल्य की परिभाषा की आवश्यकता ठीक एक संकलन इकाई में मौजूद।

+1

मैं कहूंगा कि एक ही स्थान पर निरंतर का मान वास्तव में एक प्लस है ...;) –

+0

यह दुर्भाग्यपूर्ण है, लेकिन 'एमएफआई' मानक सी नहीं है। – u0b34a0f6ae

0

आप मानक गणित परिभाषा के साथ ही काम कर रहे हैं, तो मानक हेडर फाइल math.h कुछ अच्छे होते हैं:

#include <math.h> 
    ... 
double area = radius * radius * M_PI; 

वैश्विक स्थिरांक को परिभाषित करने के लिए, वहाँ कई तरीके, पर्याप्त रूप से अन्य उत्तर में विस्तार से बताया है।

+0

यह दुर्भाग्यपूर्ण है, लेकिन 'M_PI' मानक सी नहीं है। – u0b34a0f6ae

-1

प्रीप्रोसेसर प्रत्यक्ष संकलन से पहले वास्तविक कोड द्वारा प्रतिस्थापित करेगा, इसलिए आपके मामले में आपकी पहली फ़ाइल की पीआई 3.14 द्वारा प्रतिस्थापित होगी ... और पहले अनुवाद इकाई की प्रतीक तालिका में पीआई प्रतीक नहीं है। तो जीडीबी कोई 'पीआई' प्रतीक नहीं कहेंगे।

यदि आप #define का उपयोग करना चाहते हैं और हेडर फ़ाइल का उपयोग नहीं करना चाहते हैं, तो आपको प्रत्येक फ़ाइल की शुरुआत में #deine PI की आवश्यकता है।

0

यदि आप मुख्य स्रोत फ़ाइल में शामिल फ़ाइल के लिए हेडर फ़ाइल बनाते हैं तो यह बहुत अच्छा होगा, और यह भी एक अच्छी प्रैटिस है और आप अपने सी भाषा कौशल में सुधार करेंगे। कल्पना कीजिए कि हम एक काम करता है, वैश्विक चर और स्थिरांक है कि हम मुख्य स्रोत फ़ाइल में की आवश्यकता होगी के साथ एक स्रोत फ़ाइल है, तो हम उस फ़ाइल के लिए एक हेडर फाइल बना सकते हैं कि और वहाँ उन कार्यों डाल: में

#ifndef _FILE_H 
#define _FILE_H 

#include "file.h" 
#define PI 3.14 
/** 
    *functions protypes here or other constants or globlal variables 
    */ 
    void do_something(char **param1, int *param2); 

#endif 

अपने " file.c "फ़ाइल आप folowing करना चाहिए: अपने में

#inlcude "file.h" 

void do_something(char **param1, int *param2) 
{ 

    /** 
    *do something 
    */ 
} 

" main.c "फ़ाइल आपको क्या करना चाहिए:

#include "file.h" 

/** 
    *Now you can use "PI" 
    */ 

मुझे आशा है कि मैं किसी भी तरह की मदद की।

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