c - मुझे सी में प्रत्येक बार डेटा प्रकार निर्दिष्ट क्यों करना है?




compiler-construction printf (8)

क्या संकलक यह पहचानने के लिए पर्याप्त परिपक्व नहीं है कि जब मैंने अपना चर घोषित किया?

नहीं।

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

यही कारण है कि सी और सी ++ पसंद की भाषाएं रहते हैं जब आप वास्तव में, वास्तव में तेज़, कुशल या धातु के करीब होने की परवाह करते हैं।

जैसा कि आप नीचे दिए गए कोड स्निपेट से देख सकते हैं, मैंने एक चर चर और एक int चर घोषित कर दिया है। जब कोड संकलित हो जाता है, तो उसे डेटा प्रकारों के चर प्रकार और i की पहचान करनी चाहिए।

मुझे अपने चर को स्कैन करने के दौरान फिर से बताने की आवश्यकता क्यों है कि यह स्कैन करने के लिए %s या %d निर्दिष्ट करके स्ट्रिंग या पूर्णांक चर है? क्या संकलक यह समझने के लिए पर्याप्त परिपक्व नहीं है कि जब मैंने अपने चर घोषित किए?

#include <stdio.h>

int main ()
{
  char str [80];
  int i;

  printf ("Enter your family name: ");
  scanf ("%s",str);  
  printf ("Enter your age: ");
  scanf ("%d",&i);

  return 0;
}

ऐसा इसलिए है क्योंकि फ़ंक्शन को बताने का यही एकमात्र तरीका है (जैसे printf scanf ) कि आप किस प्रकार का मान गुजर रहे हैं। उदाहरण के लिए-

int main()
{
    int i=22;
    printf("%c",i);
    return 0;
}

यह कोड चरित्र को पूर्णांक 22 नहीं प्रिंट करेगा। क्योंकि आपने चर के रूप में चर के इलाज के लिए printf फ़ंक्शन को बताया है।


क्योंकि printf में आप डेटा प्रकार निर्दिष्ट नहीं कर रहे हैं, आप डेटा प्रारूप निर्दिष्ट कर रहे हैं। यह किसी भी भाषा में एक महत्वपूर्ण भेद है, और यह सी में दोगुना महत्वपूर्ण है।

जब आप %s साथ स्ट्रिंग में स्कैन करते हैं, तो आप यह नहीं कह रहे हैं "मेरे स्ट्रिंग चर के लिए एक स्ट्रिंग इनपुट पार्स करें।" आप यह नहीं कह सकते कि सी में क्योंकि सी में स्ट्रिंग प्रकार नहीं है। सबसे करीबी चीज सी को एक स्ट्रिंग वैरिएबल है जो एक निश्चित आकार का वर्ण सरणी है जिसमें एक स्ट्रिंग का प्रतिनिधित्व करने वाले वर्ण होते हैं, जिसमें एक शून्य वर्ण द्वारा इंगित स्ट्रिंग के अंत होते हैं। तो आप वास्तव में क्या कह रहे हैं "स्ट्रिंग को पकड़ने के लिए यहां एक सरणी है, मैं वादा करता हूं कि यह स्ट्रिंग इनपुट के लिए काफी बड़ा है जिसे मैं पार्स करना चाहता हूं।"

आदिम? बेशक। 40 साल पहले सी का आविष्कार किया गया था, जब एक ठेठ मशीन में 64K रैम था। ऐसे माहौल में, रैम को संरक्षित करने से परिष्कृत स्ट्रिंग मैनिपुलेशन की तुलना में अधिक प्राथमिकता थी।

फिर भी, %s स्कैनर अधिक उन्नत प्रोग्रामिंग वातावरण में बनी हुई है, जहां स्ट्रिंग डेटा प्रकार हैं। क्योंकि यह टाइपिंग के बारे में स्कैनिंग के बारे में है।


चूंकि परिवर्तनीय तर्कों के प्रकारों को जानने के लिए scanf और printf जैसे परिवर्तनीय तर्क फ़ंक्शन के लिए कोई पोर्टेबल तरीका नहीं है, यहां तक ​​कि कितने तर्क पारित नहीं किए जाते हैं।

सी अकसर किये गए सवाल देखें: मैं कैसे खोज सकता हूं कि फ़ंक्शन को वास्तव में कितने तर्कों के साथ बुलाया गया था?

यही कारण है कि वेरिएबल तर्कों की संख्या, और शायद प्रकार निर्धारित करने के लिए कम से कम एक निश्चित तर्क होना चाहिए। और यह तर्क (मानक इसे parmN कहते हैं, सी 11 देखें ( आईएसओ / आईईसी 98 99 : 201x) §7.16 परिवर्तनीय तर्क ) इस विशेष भूमिका निभाते हैं, और मैक्रो va_start को पारित किया जाएगा। दूसरे शब्द में, आपके पास मानक सी में प्रोटोटाइप के साथ कोई फ़ंक्शन नहीं हो सकता है:

void foo(...);

पहला पैरामीटर एक प्रारूप स्ट्रिंग है । यदि आप दशमलव संख्या प्रिंट कर रहे हैं, तो ऐसा लगता है:

  • "%d" (दशमलव संख्या)
  • "%5d" (रिक्त स्थान के साथ चौड़ाई 5 तक दशमलव संख्या)
  • "%05d" (दशमलव संख्या शून्य के साथ चौड़ाई 5 तक गद्देदार)
  • "%+d" (दशमलव संख्या, हमेशा एक चिह्न के साथ)
  • "Value: %d\n" (संख्या से पहले / बाद में कुछ सामग्री)

इत्यादि, उदाहरण के लिए विकिपीडिया पर प्रारूप प्लेसहोल्डर्स को यह पता लगाने के लिए देखें कि प्रारूप स्ट्रिंग में क्या हो सकता है।

यहां एक से अधिक पैरामीटर भी हो सकते हैं:

"%s - %d" (एक स्ट्रिंग, फिर कुछ सामग्री, फिर एक संख्या)


प्रोटोटाइप int scanf ( const char * format, ... ); scanf रूप में int scanf ( const char * format, ... ); स्टोर्स को अतिरिक्त तर्कों द्वारा इंगित स्थानों में पैरामीटर प्रारूप के अनुसार डेटा दिया गया है।

यह कंपाइलर से संबंधित नहीं है, यह स्कैनफ के लिए परिभाषित वाक्यविन्यास के बारे में है। पैरामीटर प्रारूप को डेटा के प्रवेश के लिए आकार के बारे में स्कैनफ को जानने के लिए आवश्यक है।


printf एक आंतरिक कार्य नहीं है । यह प्रति भाषा सी भाषा का हिस्सा नहीं है। सभी कंपाइलर printf को कॉल करने के लिए कोड उत्पन्न करते हैं, जो भी पैरामीटर पास करते हैं। अब, क्योंकि सी रन टाइम पर टाइप जानकारी को समझने के लिए एक तंत्र के रूप में reflection प्रदान नहीं करता है, प्रोग्रामर को स्पष्ट रूप से आवश्यक जानकारी प्रदान करना होता है।


printf और scanf I / O फ़ंक्शंस हैं जिन्हें नियंत्रण स्ट्रिंग और तर्कों की एक सूची प्राप्त करने के तरीके में डिज़ाइन और परिभाषित किया गया है।

फ़ंक्शंस को पास किए गए पैरामीटर के प्रकार को नहीं पता है, और कंपाइलर भी इस जानकारी को पास नहीं कर सकता है।