2010-12-10 9 views
26

मानचित्र को #include <map> के रूप में क्यों आयात किया गया है, लेकिन stdio #include <stdio.h> के रूप में आयात किया गया है?कुछ लोगों को .h और दूसरों की आवश्यकता क्यों नहीं है?

+2

stdio के रूप में भी '# शामिल ' – mkb

+0

@Matt आयात किया जा सकता: तो आयात नाम फ़ाइल नाम से अलग है। यह कैसे किया जाता है? – Casebash

+0

@Casebach: आमतौर पर 'stdio.h' सहित 'cstdio' के साथ दो अलग-अलग फाइलें,' cstdio' और' stdio.h' होती हैं, जो इस तरह के सभी प्रतीकों को नेमस्पेस std में रखती हैं। लेकिन यह सही तरीका है जिसमें यह कार्यान्वयन पर निर्भर करता है। –

उत्तर

27

सभी मानक सी ++ हेडर अंत में .h नहीं चाहते हैं। मैंने कहीं पढ़ा है अवधारणा है कि वे वास्तविक फ़ाइलें होने की जरूरत नहीं है कि, भले ही मैं एक कार्यान्वयन कभी नहीं देखा था एक और तरीके सेसंपादन में यह कार्य करें: वास्तव में संकलक intrinsics पर विचार काम करना चाहिए हेडर शामिल है, लेकिन वास्तव में उन्हें फाइल के रूप में शामिल नहीं करते हैं; @Yttrill की टिप्पणी देखें।

stdio.h चीज़ के लिए, एक सी ++ एप्लिकेशन में आपको <stdio.h> शामिल नहीं करना चाहिए, लेकिन इसके बजाय आपको <cstdio> शामिल करना चाहिए। आम तौर पर, आपको "सामान्य" सी हेडर शामिल नहीं करना चाहिए, लेकिन उनके सी ++ - ized समकक्ष, जिन्हें .h अंत में नहीं मिला है, c सामने और में std में परिभाषित सभी प्रतीकों को डालें नामस्थान। तो, <math.h><cmath>, <stdlib.h><cstdlib> बन जाता है, और इसी तरह।

सामान्य रूप से, आपको वैश्विक नामस्थान को प्रदूषित करने से बचने के लिए सी हेडर के सी ++ - ized संस्करणों का उपयोग करना चाहिए (मान लीजिए कि आप उन लोगों में से एक नहीं हैं जो using namespace std; हर जगह डालते हैं) और कुछ सी ++ सुधारों के लाभ के लिए मानक सी शीर्षलेख (उदाहरण के लिए कुछ गणित कार्यों में अधिभार जोड़ा गया)।


सामान्य रूप से, इस पूरी चीज के कार्यान्वयन को ऐसी निर्देशिका में विस्तार के बिना किया जाता है जिसमें संकलक हेडर फाइलों की तलाश करता है। मेरे जी ++ 4 में।4 स्थापना, उदाहरण के लिए, आपके पास:

[email protected]:/usr/include/c++/4.4$ ls 
algorithm   cstdarg    functional  sstream 
array    cstdatomic   initializer_list stack 
backward   cstdbool    iomanip   stdatomic.h 
bits    cstddef    ios    stdexcept 
bitset    cstdint    iosfwd   streambuf 
c++0x_warning.h  cstdio    iostream   string 
cassert    cstdlib    istream   system_error 
ccomplex   cstring    iterator   tgmath.h 
cctype    ctgmath    limits   thread 
cerrno    ctime    list    tr1 
cfenv    cwchar    locale   tr1_impl 
cfloat    cwctype    map    tuple 
chrono    cxxabi-forced.h  memory   typeinfo 
cinttypes   cxxabi.h    mutex    type_traits 
ciso646    debug    new    unordered_map 
climits    deque    numeric   unordered_set 
clocale    exception   ostream   utility 
cmath    exception_defines.h parallel   valarray 
complex    exception_ptr.h  queue    vector 
complex.h   ext     random   x86_64-linux-gnu 
condition_variable fenv.h    ratio 
csetjmp    forward_list   regex 
csignal    fstream    set 

सी ++ - ized सी हेडर सिद्धांत में सिर्फ एक

namespace std 
{ 
#include <original_C_header.h> 
}; 

हो सकता है लेकिन सामान्य रूप में वे और अधिक कार्यान्वयन विशेष से निपटने के लिए जटिल हैं समस्याएं (विशेष रूप से मैक्रोज़ के संबंध में) और सी ++ - संबंधित कार्यक्षमता जोड़ने के लिए (उदाहरण के लिए <cmath> में अतिरिक्त अधिभारों का पिछला उदाहरण देखें)।


वैसे, सी ++ मानक (§D.5) मत कहो कि <c***> हेडर व्यवहार करना चाहिए जैसे कि वे एक namespace std निर्देश में <***.h> हेडर शामिल है, लेकिन विपरीत:

मानक सी लाइब्रेरी के साथ संगतता के लिए, सी ++ मानक लाइब्रेरी 18 सी हेडर प्रदान करती है [...] प्रत्येक सी शीर्षलेख, जिसका नाम फॉर्म नाम है। एच, व्यवहार करता है जैसे प्रत्येक नाम मानक लाइब्रेरी नेमस्पेस में संबंधित है cname हेडर को नाम-स्थान std के नेमस्पेस दायरे में भी रखा गया है और इसके बाद एक स्पष्ट उपयोग-घोषणा (7.3.3)

सूचना है कि इस तरह हेडर पदावनत (§C.2.1) माना जाता है, तो यह मुख्य कारण है कि आप उन्हें प्रयोग नहीं करना चाहिए है:

C.2.1 संशोधन हेडर संगतता के लिए करने के लिए मानक सी लाइब्रेरी के साथ, सी ++ मानक लाइब्रेरी 18 सी हेडर (डी 5), प्रदान करती है लेकिन उनका उपयोग सी ++ में बहिष्कृत है।

+5

के बाद से Matteo वास्तव में सी ++ सी मानक हेडर की संस्करणों का उपयोग के लिए किसी भी कारणवश नहीं प्रदान की थी, मैं एक दे देंगे तर्कों का। सी इन एकाधिक संस्करणों को भी प्रदान करता है, लेकिन उनके सभी अलग-अलग नाम हैं (उदा। 'Abs' बनाम' fabs' बनाम 'fabs' बनाम' fabsl')। यदि आप टेम्पलेट का उपयोग कर रहे हैं, और अन्यथा अन्य हेडर के लिए नहीं, तो # #'के साथ यह अंतर बनाता है। –

+0

@Ben वोइट: मजेदार, मैं इसे स्वतंत्र रूप से पिछले संशोधन में जोड़ा :) –

+1

नाम स्थान प्रदूषण वास्तव में एक कारण हेडर की सी ++ संस्करण का उपयोग करने के ज्यादा नहीं है ('cmath' फाइल करने के लिए एक नज़र होने के बाद), के बाद से उनके सही मन में कोई भी नामकरण का प्रयोग करेंगे कि सी मानक पुस्तकालय –

2

यह डिस्क पर वास्तविक फ़ाइल का नाम है। आपके मानक में निर्देशिका (0) map.h या stdio नामक कोई फ़ाइल नहीं है।

सी ++ मानक पुस्तकालय फ़ाइल नामों के अंत में .h नहीं होने की दिशा में .h का उपयोग करने की पिछली शैली से दूर चला गया।

#include<vector> 

vector<int> v; 

(निरोधक टिप्पणी:। जी हाँ, मुझे जरूरतों std:: निर्माण करने के लिए पता है, लेकिन यह सिर्फ एक उदाहरण है)

यह हो सकता है संभवतः वाक्य रचना अधिक टेम्पलेट्स की तरह लग रहे बनाने से संबंधित कर दिया गया है
+0

मैं प्रतिस्पर्धात्मक उत्तर को कम करना नहीं चाहता हूं, लेकिन यह वास्तव में गलत है - इस बात की कोई गारंटी नहीं है कि डिस्क पर फ़ाइलें 'map' या 'stdio.h' मौजूद हैं। –

+0

यह सच है, कोई गारंटी नहीं है। अधिकांश कंपाइलर मानक लाइब्रेरी हेडर को डिस्क पर फ़ाइलों के रूप में संग्रहीत करते हैं, हालांकि - निश्चित रूप से लोकप्रिय आमतौर पर लोकप्रिय होते हैं। –

+0

निश्चित - यह स्पष्ट कार्यान्वयन विकल्प है। मैंने डाउनवोट नहीं किया था, बस यह देखना चाहता था कि "यह डिस्क पर वास्तविक फ़ाइल का नाम है" मानक तक जाने तक सख्ती से सटीक नहीं है। –

2

यह सी ++ मानक द्वारा परिभाषित किया गया है - जैसा कि होता है, map और stdio.h वास्तविक फ़ाइलों को भी नहीं होना चाहिए।

एक साइड-नोट के रूप में, stdio.h वह शीर्षलेख है जिसे मूल रूप से सी मानक पुस्तकालयों से सी ++ में आयात किया गया था - सी ++ संस्करण cstdio है। व्यावहारिक शब्दों में, इसका आम तौर पर मतलब है कि जब आप cstdio इसके बजाय, stdio.h से सामान प्राप्त करते हैं, लेकिन यह नामस्थान std में है।

बस स्पष्ट करने के लिए: stdio.h आप सी ++ में शामिल हैं मूल रूप से सी हेडर का सी ++ संस्करण है। लेकिन शामिल करने का सी ++ तरीका cstdio है।

+1

नहीं है, '# शामिल ' एक C++ कार्यक्रम आप सी मानक पुस्तकालयों से संस्करण देना नहीं है (या वैसे भी यह माना जाता नहीं है), http://stackoverflow.com/questions/4405887/when-the- देखना सी मानक प्रदान करता है-सी हेडर लाने-नाम-में-वैश्विक नाम स्थान –

+0

@Ben: वास्तव में, मैं यह गलत phrased - मुझे लगता है कि यह सी में शामिल ++ लिखने के सी-शैली तरीका है कहते हैं कि करने के लिए होती, और यह चीजों को नेमस्पेस std में नहीं डालता है। हेडर अक्सर सी ++ सी मानक पुस्तकालय कार्यों, जो वास्तविक डेटा प्रकार के लिए अनुकूलित कर रहे हैं की अतिभारित संस्करण प्रदान: –

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