C डेटा प्रकार "अधिकांश कंप्यूटरों द्वारा सीधे समर्थित" कैसे होते हैं?


114

मैं K & R की "द सी प्रोग्रामिंग लैंग्वेज" पढ़ रहा हूं और इस कथन के साथ आया हूं [परिचय, पृष्ठ। 3]:

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

बोल्ड स्टेटमेंट का क्या मतलब है? क्या डेटा प्रकार या नियंत्रण संरचना का उदाहरण है जो सीधे कंप्यूटर द्वारा समर्थित नहीं है?


1
इन दिनों, सी भाषा जटिल अंकगणित का समर्थन करती है, लेकिन मूल रूप से ऐसा नहीं हुआ क्योंकि कंप्यूटर सीधे डेटा के रूप में जटिल संख्या का समर्थन नहीं करते हैं।
जोनाथन लेफ्लर

12
दरअसल, यह ऐतिहासिक रूप से दूसरा रास्ता था: C को उस समय उपलब्ध हार्डवेयर संचालन और प्रकारों से डिजाइन किया गया था।
बेसिल स्टारीनेविच

2
अधिकांश कंप्यूटरों में दशमलव फ़्लोट्स के लिए कोई प्रत्यक्ष हार्डवेयर समर्थन नहीं है
प्लाज़्माएच

3
@MSalters: "क्या मैं डेटा प्रकार या नियंत्रण संरचना का उदाहरण है जो सीधे कंप्यूटर द्वारा समर्थित नहीं है?" जिसे मैंने K & R
PlasmaHH

11
स्टैक ओवरफ्लो शुरू होने के 6 साल से अधिक समय बाद यह डुप्लिकेट कैसे नहीं है?
पीटर मोर्टेंसेन

जवाबों:


143

हां, ऐसे डेटा प्रकार हैं जो सीधे समर्थित नहीं हैं।

कई एम्बेडेड सिस्टम पर, कोई हार्डवेयर फ़्लोटिंग पॉइंट यूनिट नहीं है। तो, जब आप इस तरह कोड लिखते हैं:

float x = 1.0f, y = 2.0f;
return x + y;

यह कुछ इस तरह से अनुवादित हो जाता है:

unsigned x = 0x3f800000, y = 0x40000000;
return _float_add(x, y);

तब कंपाइलर या मानक लाइब्रेरी को एक कार्यान्वयन की आपूर्ति करनी होती है _float_add(), जो आपके एम्बेडेड सिस्टम पर मेमोरी ले जाती है। यदि आप एक बहुत छोटे सिस्टम पर बाइट्स गिन रहे हैं, तो यह जोड़ सकता है।

एक अन्य आम उदाहरण 64-बिट पूर्णांक ( long long1999 से सी मानक में) है, जो सीधे 32-बिट सिस्टम द्वारा समर्थित नहीं हैं। पुराने SPARC सिस्टम पूर्णांक गुणन का समर्थन नहीं करते हैं, इसलिए गुणा को रनटाइम द्वारा आपूर्ति की जानी थी। अन्य उदाहरण हैं।

अन्य भाषाएँ

तुलना करके, अन्य भाषाओं में अधिक जटिल आदिम हैं।

उदाहरण के लिए, एक लिस्प प्रतीक को बहुत अधिक रनटाइम समर्थन की आवश्यकता होती है, जैसे कि लुआ में टेबल, पायथन में तार, फोर्ट्रान में एरे, एट वगैरह। C में समतुल्य प्रकार आमतौर पर या तो मानक पुस्तकालय का हिस्सा नहीं होते हैं (कोई मानक चिह्न या टेबल नहीं) या वे बहुत सरल होते हैं और उन्हें बहुत अधिक रनटाइम समर्थन की आवश्यकता नहीं होती है (C में सरणियाँ मूल रूप से सिर्फ संकेत हैं, शून्य-समाप्त तार हैं लगभग उतना ही सरल)।

नियंत्रण संरचनाओं

सी से गायब एक उल्लेखनीय नियंत्रण संरचना अपवाद हैंडलिंग है। नॉनक्लॉक एग्जिट सीमित है setjmp()और longjmp(), जो प्रोसेसर स्टेट के कुछ हिस्सों को सिर्फ सहेजता है और पुनर्स्थापित करता है। तुलना करके, C ++ रनटाइम को स्टैक चलना और डिस्ट्रक्टर्स और अपवाद हैंडलर को कॉल करना है।


2
मूल रूप से सिर्फ संकेत ... बल्कि, मूल रूप से सिर्फ स्मृति के कच्चे टुकड़े। भले ही वह नाइट-पिकिंग हो, और उत्तर वैसे भी अच्छा है।
डेडुप्लिकेटर

2
आप यह तर्क दे सकते हैं कि अशक्त समाप्त तारों में "हार्डवेयर समर्थन" होता है क्योंकि स्ट्रिंग टर्मिनेटर ज्यादातर प्रोसेसर के 'शून्य' ऑपरेशन को 'जंप' करता है और इस तरह से तार के अन्य संभावित कार्यान्वयनों की तुलना में थोड़ा तेज होता है।
पीटरिस

1
कैसे सी बस asm को मैप करने के लिए डिज़ाइन किया गया है पर विस्तार करने के लिए मेरा अपना जवाब पोस्ट किया।
पीटर कॉर्डेस

1
कृपया कोलाजेशन का उपयोग न करें "सरणियां मूल रूप से सिर्फ संकेत हैं", यह ओपी की तरह एक शुरुआत को बुरी तरह से भ्रमित कर सकता है। "सरणियों का उपयोग सीधे हार्डवेयर स्तर पर पॉइंटर्स का उपयोग करके किया जाता है" की तर्ज पर कुछ बेहतर आईएमओ होगा।
पैरामैग्नेटिक क्रोइसैंट

1
@ TheParamagneticCroissant: मुझे लगता है कि इस संदर्भ में यह उचित है ... शुद्धता की कीमत पर स्पष्टता आती है।
डेट्रिच एप

37

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

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

सी भाषा के लेखकों - और बी और बीसीपीएल भाषाओं ने इसे तुरंत पूर्व कर दिया - भाषा में निर्माणों को परिभाषित करने के इरादे से थे जो कि यथासंभव कुशलता से विधानसभा में संकलित किए गए थे ... वास्तव में, उन्हें लक्ष्य में सीमाओं द्वारा मजबूर किया गया था। हार्डवेयर। जैसा कि अन्य जवाबों में कहा गया है, इसमें शामिल शाखाएँ (गोटो और सी में अन्य प्रवाह नियंत्रण), चालें (असाइनमेंट), लॉजिकल ऑपरेशंस (& ^ ^), बेसिक अंकगणित (जोड़, घटाना, वेतन वृद्धि), और मेमोरी एड्रेसिंग (पॉइंटर्स) हैं। )। एक अच्छा उदाहरण सी में पूर्व / पोस्ट-इन्क्रीमेंट और डिक्रीमेंट ऑपरेटर हैं, जिन्हें केन थॉम्पसन द्वारा विशेष रूप से बी भाषा में जोड़ा गया था, क्योंकि वे एक बार संकलित किए गए एकल ओपकोड में सीधे अनुवाद करने में सक्षम थे।

यह लेखकों का मतलब है जब उन्होंने कहा "अधिकांश कंप्यूटरों द्वारा सीधे समर्थित"। वे मतलब नहीं था कि अन्य भाषाओं प्रकार और संरचनाओं कि कर रहे थे निहित नहीं सीधे समर्थित - वे का मतलब है कि द्वारा डिजाइन सी निर्माणों अनुवाद सबसे सीधे (कभी कभी सचमुच सीधे) विधानसभा में।

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

भाषा के इतिहास के एक दिलचस्प लेखन के लिए, सी भाषा का विकास देखें - डेनिस रिची


14

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

लंबे उत्तर के लिए थोड़ी सी असेंबली भाषा ज्ञान की आवश्यकता होती है। सी में, इस तरह के एक बयान:

int myInt = 10;

विधानसभा में इस तरह से अनुवाद करना होगा:

myInt dw 1
mov myInt,10

इसकी तुलना C ++ जैसी किसी चीज़ से करें:

MyClass myClass;
myClass.set_myInt(10);

परिणामी असेंबली लैंग्वेज कोड (यह निर्भर करता है कि MyClass () कितना बड़ा है), सैकड़ों असेंबली लैंग्वेज लाइन्स को जोड़ सकता है।

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

संपादित करें

मेरे जवाब पर टिप्पणियों को देखते हुए, मैंने एक परीक्षण चलाने का फैसला किया, सिर्फ अपनी पवित्रता के लिए। मैंने "test.c" नामक एक कार्यक्रम बनाया, जो इस तरह दिखता था:

#include <stdio.h>

void main()
{
    int myInt=10;

    printf("%d\n", myInt);
}

मैंने इसे gcc का उपयोग करके असेंबली के लिए संकलित किया। इसे संकलित करने के लिए मैंने निम्न कमांड लाइन का उपयोग किया:

gcc -S -O2 test.c

यहाँ परिणामस्वरूप विधानसभा भाषा है:

    .file   "test.c"
    .section    .rodata.str1.1,"aMS",@progbits,1
.LC0:
    .string "%d\n"
    .section    .text.unlikely,"ax",@progbits
.LCOLDB1:
    .section    .text.startup,"ax",@progbits
.LHOTB1:
    .p2align 4,,15
    .globl  main
    .type   main, @function
main:
.LFB24:
    .cfi_startproc
    movl    $10, %edx
    movl    $.LC0, %esi
    movl    $1, %edi
    xorl    %eax, %eax
    jmp __printf_chk
    .cfi_endproc
.LFE24:
    .size   main, .-main
    .section    .text.unlikely
.LCOLDE1:
    .section    .text.startup
.LHOTE1:
    .ident  "GCC: (Ubuntu 4.9.1-16ubuntu6) 4.9.1"
    .section    .note.GNU-stack,"",@progbits

मैं फिर "test.cpp" नामक एक फाइल बनाता हूं, जिसने एक वर्ग को परिभाषित किया और "test.c" जैसी ही चीज़ को आउटपुट किया।

#include <iostream>
using namespace std;

class MyClass {
    int myVar;
public:
    void set_myVar(int);
    int get_myVar(void);
};

void MyClass::set_myVar(int val)
{
    myVar = val;
}

int MyClass::get_myVar(void)
{
    return myVar;
}

int main()
{
    MyClass myClass;
    myClass.set_myVar(10);

    cout << myClass.get_myVar() << endl;

    return 0;
}

मैंने इसे इसी तरह संकलित किया, इस कमांड का उपयोग करते हुए:

g++ -O2 -S test.cpp

यहाँ परिणामस्वरूप विधानसभा फ़ाइल है:

    .file   "test.cpp"
    .section    .text.unlikely,"ax",@progbits
    .align 2
.LCOLDB0:
    .text
.LHOTB0:
    .align 2
    .p2align 4,,15
    .globl  _ZN7MyClass9set_myVarEi
    .type   _ZN7MyClass9set_myVarEi, @function
_ZN7MyClass9set_myVarEi:
.LFB1047:
    .cfi_startproc
    movl    %esi, (%rdi)
    ret
    .cfi_endproc
.LFE1047:
    .size   _ZN7MyClass9set_myVarEi, .-_ZN7MyClass9set_myVarEi
    .section    .text.unlikely
.LCOLDE0:
    .text
.LHOTE0:
    .section    .text.unlikely
    .align 2
.LCOLDB1:
    .text
.LHOTB1:
    .align 2
    .p2align 4,,15
    .globl  _ZN7MyClass9get_myVarEv
    .type   _ZN7MyClass9get_myVarEv, @function
_ZN7MyClass9get_myVarEv:
.LFB1048:
    .cfi_startproc
    movl    (%rdi), %eax
    ret
    .cfi_endproc
.LFE1048:
    .size   _ZN7MyClass9get_myVarEv, .-_ZN7MyClass9get_myVarEv
    .section    .text.unlikely
.LCOLDE1:
    .text
.LHOTE1:
    .section    .text.unlikely
.LCOLDB2:
    .section    .text.startup,"ax",@progbits
.LHOTB2:
    .p2align 4,,15
    .globl  main
    .type   main, @function
main:
.LFB1049:
    .cfi_startproc
    subq    $8, %rsp
    .cfi_def_cfa_offset 16
    movl    $10, %esi
    movl    $_ZSt4cout, %edi
    call    _ZNSolsEi
    movq    %rax, %rdi
    call    _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
    xorl    %eax, %eax
    addq    $8, %rsp
    .cfi_def_cfa_offset 8
    ret
    .cfi_endproc
.LFE1049:
    .size   main, .-main
    .section    .text.unlikely
.LCOLDE2:
    .section    .text.startup
.LHOTE2:
    .section    .text.unlikely
.LCOLDB3:
    .section    .text.startup
.LHOTB3:
    .p2align 4,,15
    .type   _GLOBAL__sub_I__ZN7MyClass9set_myVarEi, @function
_GLOBAL__sub_I__ZN7MyClass9set_myVarEi:
.LFB1056:
    .cfi_startproc
    subq    $8, %rsp
    .cfi_def_cfa_offset 16
    movl    $_ZStL8__ioinit, %edi
    call    _ZNSt8ios_base4InitC1Ev
    movl    $__dso_handle, %edx
    movl    $_ZStL8__ioinit, %esi
    movl    $_ZNSt8ios_base4InitD1Ev, %edi
    addq    $8, %rsp
    .cfi_def_cfa_offset 8
    jmp __cxa_atexit
    .cfi_endproc
.LFE1056:
    .size   _GLOBAL__sub_I__ZN7MyClass9set_myVarEi, .-_GLOBAL__sub_I__ZN7MyClass9set_myVarEi
    .section    .text.unlikely
.LCOLDE3:
    .section    .text.startup
.LHOTE3:
    .section    .init_array,"aw"
    .align 8
    .quad   _GLOBAL__sub_I__ZN7MyClass9set_myVarEi
    .local  _ZStL8__ioinit
    .comm   _ZStL8__ioinit,1,1
    .hidden __dso_handle
    .ident  "GCC: (Ubuntu 4.9.1-16ubuntu6) 4.9.1"
    .section    .note.GNU-stack,"",@progbits

जैसा कि आप स्पष्ट रूप से देख सकते हैं, परिणामस्वरूप असेंबली फ़ाइल C ++ फ़ाइल पर बहुत बड़ी है तो यह C फ़ाइल पर है। यहां तक ​​कि अगर आप अन्य सभी सामानों को काटते हैं और केवल C "मुख्य" की तुलना C ++ "मुख्य" से करते हैं, तो बहुत अधिक अतिरिक्त सामान होता है।


14
वह "C ++ कोड" सिर्फ C ++ नहीं है। और वास्तविक कोड जैसे कि MyClass myClass { 10 }C ++ में ठीक उसी विधानसभा के संकलन की संभावना है। आधुनिक सी ++ संकलक ने अमूर्त दंड को समाप्त कर दिया है। और परिणामस्वरूप, वे अक्सर सी कंपाइलरों को हरा सकते हैं। जैसे कि C का अमूर्त दंड qsortवास्तविक है, लेकिन C ++ का std::sortमूल अनुकूलन के बाद भी अमूर्त दंड नहीं है।
11

1
आप आसानी से आईडीए प्रो का उपयोग करके देख सकते हैं कि अधिकांश सी ++ कंस्ट्रक्शन एक ही चीज़ को संकलित करते हैं क्योंकि इसे सी में मैन्युअल रूप से कर रहे हैं, कंस्ट्रक्टर और डावर्स तुच्छ वस्तुओं के लिए अंतर्निर्मित हो जाते हैं, फिर भविष्य के अनुकूलन को लागू किया जाता है
पॉलम

7

K & R का अर्थ है कि अधिकांश C अभिव्यक्तियाँ (तकनीकी अर्थ) एक या कुछ विधानसभा निर्देशों के लिए मानचित्र, न कि किसी फ़ंक्शन लायब्रेरी के लिए फ़ंक्शन कॉल। सामान्य अपवाद एक हार्डवेयर div निर्देश के बिना आर्किटेक्चर पर पूर्णांक विभाजन है, या बिना FPU वाली मशीनों पर फ़्लोटिंग पॉइंट।

एक उद्धरण है:

सी विधानसभा भाषा के उपयोगकर्ता-मित्रता के साथ विधानसभा भाषा के लचीलेपन और शक्ति को जोड़ती है।

( यहां पाया गया । मुझे लगा कि मुझे एक भिन्न भिन्नता याद है, जैसे "असेंबली लैंग्वेज की सुविधा और असेंबली लैंग्वेज की गति।"

long int आमतौर पर देशी मशीन के रजिस्टरों के समान चौड़ाई होती है।

कुछ उच्च स्तरीय भाषाएं अपने डेटा प्रकारों की सटीक चौड़ाई को परिभाषित करती हैं, और सभी मशीनों पर कार्यान्वयन समान होना चाहिए। सी नहीं, हालांकि।

यदि आप x86-64 पर 128 बिट इनट के साथ काम करना चाहते हैं, या सामान्य मामले में बिगइंटियर के मनमाने आकार के लिए, तो आपको इसके लिए कार्यों की लाइब्रेरी की आवश्यकता है। सभी सीपीयू अब नकारात्मक पूर्णांक के द्विआधारी प्रतिनिधित्व के रूप में 2s पूरक का उपयोग करते हैं, लेकिन यहां तक ​​कि जब सी डिजाइन किया गया था तब भी ऐसा नहीं था। (यही कारण है कि कुछ चीजें जो गैर-2-पूरक मशीनों पर अलग-अलग परिणाम देती हैं, सी मानकों में तकनीकी रूप से अपरिभाषित हैं।)

C संकेत डेटा या फ़ंक्शंस के लिए उसी तरह काम करते हैं जैसे असेंबली एड्रेस।

यदि आप संदर्भों की गिनती चाहते हैं, तो आपको इसे स्वयं करना होगा। यदि आप चाहते हैं कि c ++ वर्चुअल मेंबर फंक्शन जो किसी अलग फ़ंक्शन को कॉल करता है, वह इस बात पर निर्भर करता है कि आपका पॉइंटर किस तरह की वस्तु की ओर इशारा कर रहा है, तो C ++ कंपाइलर को callएक निश्चित पते के साथ केवल एक इंस्ट्रक्शन से बहुत अधिक उत्पन्न करना पड़ता है ।

स्ट्रिंग्स सिर्फ ऐरे हैं

लाइब्रेरी फ़ंक्शंस के बाहर, प्रदान किए गए एकमात्र स्ट्रिंग ऑपरेशन एक चरित्र को पढ़ने / लिखने के लिए हैं। कोई कॉनसैट, कोई विकल्प नहीं, कोई खोज नहीं। (स्ट्रिंग्स को '\0'8-पूर्णांक के शून्य-समाप्त ( ) सरणियों के रूप में संग्रहीत किया जाता है , सूचक + लंबाई नहीं, इसलिए एक विकल्प प्राप्त करने के लिए आपको मूल स्ट्रिंग में एक nul लिखना होगा।)

सीपीयू में कभी-कभी एक स्ट्रिंग-खोज फ़ंक्शन द्वारा उपयोग के लिए डिज़ाइन किए गए निर्देश होते हैं, लेकिन फिर भी आमतौर पर निष्पादित किए गए निर्देशों के अनुसार एक बाइट की प्रक्रिया लूप में होती है। (या x86 प्रतिनिधि उपसर्ग के साथ। हो सकता है कि यदि C को x86 पर डिज़ाइन किया गया था, तो लाइब्रेरी फ़ंक्शन कॉल के बजाय स्ट्रिंग खोज या तुलना एक देशी ऑपरेशन होगी।)

कई अन्य उत्तर उन चीजों का उदाहरण देते हैं जो मूल रूप से समर्थित नहीं हैं, जैसे अपवाद हैंडलिंग, हैश टेबल, सूचियां। K & R के डिजाइन दर्शन का कारण है C का इनमें से कोई भी मूल नहीं है।


"के एंड आर का मतलब है कि अधिकांश सी एक्सप्रेशंस (तकनीकी अर्थ) एक या कुछ असेंबली निर्देशों के लिए मैप करते हैं, न कि सपोर्ट लाइब्रेरी के लिए फंक्शन कॉल।" यह बहुत सहज व्याख्या है। धन्यवाद।
gwg

1
मैं अभी "वॉन न्यूमैन भाषा" ( en.wikipedia.org/wiki/Von_Neumann_programming_languages ) शब्द पर आया हूं । यह वास्तव में सी क्या है।
पीटर कॉर्ड्स

1
यह ठीक इसी तरह है कि मैं सी का उपयोग करता हूं। लेकिन मैंने जो कुछ भी सीखा है उससे मुझे आश्चर्य हुआ है कि हार्डवेयर की एक विस्तृत श्रृंखला के लिए कुशल होने का प्रयास करके यह कभी-कभी सबसे आधुनिक हार्डवेयर में अयोग्य और अक्षम है। उदाहरण के लिए मेरा मतलब है कि कोई उपयोगी-और-विश्वसनीय-से-पता लगाने वाला-पूर्णांक-ओवरफ़्लो-इन-सी और बहु-शब्द-अतिरिक्त-का-उपयोग-ले-फ़्लैग
जेड बोसोन

6

किसी प्रक्रिया की असेंबली भाषा आम तौर पर जम्प (गो), स्टेटमेंट, मूव स्टेटमेंट, बाइनरी ऑर्थ्रेटिक (XOR, NAND, AND OR, आदि), मेमोरी फील्ड्स (या एड्रेस) से संबंधित होती है। मेमोरी को दो प्रकारों, निर्देश और डेटा में वर्गीकृत करता है। यह सब के बारे में एक विधानसभा भाषा है (मुझे यकीन है कि विधानसभा प्रोग्रामरों का तर्क है कि इससे कहीं अधिक है, लेकिन यह सामान्य रूप से इस पर उबलता है)। सी बारीकी से इस सादगी जैसा दिखता है।

C को इकट्ठा करना है कि बीजगणित अंकगणित के लिए क्या है।

सी असेंबली की मूल बातें (प्रोसेसर की भाषा) को एन्क्रिप्ट करता है। संभवत: "की तुलना में सी द्वारा प्रदान किए गए डेटा प्रकार और नियंत्रण संरचनाएं अधिकांश कंप्यूटरों द्वारा समर्थित हैं"


5

भ्रामक तुलनाओं से सावधान रहें

  1. बयान एक "रन-टाइम लाइब्रेरी" की धारणा पर निर्भर करता है , जो ज्यादातर फैशन से बाहर हो गया है, कम से कम मुख्यधारा की उच्च स्तरीय भाषाओं के लिए। (यह अभी भी सबसे छोटे एम्बेडेड सिस्टम के लिए प्रासंगिक है।) रन-टाइम उस भाषा में एक प्रोग्राम का न्यूनतम समर्थन है, जब आपको भाषा में निर्मित केवल निर्माण का उपयोग करना होता है (जैसा कि लाइब्रेरी द्वारा प्रदान किए गए फ़ंक्शन को स्पष्ट रूप से कॉल करने के लिए विरोध किया जाता है) ।
  2. इसके विपरीत, आधुनिक भाषाएं रन-टाइम और मानक पुस्तकालय के बीच भेदभाव नहीं करती हैं , बाद वाला अक्सर व्यापक होता है।
  3. K & R पुस्तक के समय, C के पास एक मानक पुस्तकालय भी नहीं था । बल्कि, यू सीक्स के विभिन्न स्वादों के बीच उपलब्ध सी लाइब्रेरी काफी अलग थीं।
  4. कथन को समझने के लिए आपको एक मानक पुस्तकालय (जैसे कि अन्य उत्तरों में उल्लिखित लुआ और पायथन) के साथ भाषाओं की तुलना नहीं करनी चाहिए , लेकिन अधिक अंतर्निहित निर्माण वाली भाषाओं (जैसे कि पुराने दिनों के LISP और अन्य दिनों में उल्लिखित पुराने लेख) जवाब)। अन्य उदाहरण बेसिक (इंटरैक्टिव, जैसे LISP) या PASCAL (संकलित, FORTRAN की तरह) होंगे, जो दोनों (अन्य बातों के अलावा) इनपुट / आउटपुट सुविधाओं का अधिकार भाषा में ही बनाया गया है।
  5. इसके विपरीत, एक सी प्रोग्राम से गणना परिणामों को प्राप्त करने का कोई मानक तरीका नहीं है जो केवल रन-टाइम का उपयोग कर रहा है, किसी भी पुस्तकालय का नहीं।

दूसरी ओर, अधिकांश आधुनिक भाषाएं समर्पित रनटाइम वातावरण के अंदर चलती हैं जो कचरा संग्रहण जैसी सुविधाएं प्रदान करती हैं।
नैट CK

5

क्या एक डेटा प्रकार या एक नियंत्रण संरचना का एक उदाहरण है जो सीधे कंप्यूटर द्वारा समर्थित नहीं है?

सी भाषा में सभी मूलभूत डेटा प्रकार और उनके संचालन को बिना लूपिंग के एक या कुछ मशीन-भाषा निर्देशों द्वारा लागू किया जा सकता है - वे सीधे (व्यावहारिक रूप से हर) सीपीयू द्वारा समर्थित हैं।

कई लोकप्रिय डेटा प्रकार और उनके संचालन के लिए दर्जनों मशीन-भाषा निर्देशों की आवश्यकता होती है, या कुछ रनटाइम लूप या दोनों की पुनरावृत्ति की आवश्यकता होती है।

कई भाषाओं में ऐसे प्रकारों और उनके कार्यों के लिए विशेष संक्षिप्त वाक्यविन्यास होता है - ऐसे डेटा प्रकारों का उपयोग करके सी में आमतौर पर बहुत अधिक कोड टाइप करने की आवश्यकता होती है।

इस तरह के डेटा प्रकार, और संचालन में शामिल हैं:

  • मनमाने ढंग से लंबाई के पाठ स्ट्रिंग हेरफेर - संघनन, प्रतिस्थापन, एक नए स्ट्रिंग को कुछ अन्य स्ट्रिंग, आदि ('s = "हैलो वर्ल्ड!"; s = (s + s) [2: -2] के साथ आरंभ करने के लिए एक नया स्ट्रिंग असाइन करना। पायथन में)
  • सेट
  • नेस्टेड वर्चुअल डिस्ट्रक्टर्स वाली वस्तुएं, जैसे कि C ++ और हर दूसरे ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग लैंग्वेज में
  • 2 डी मैट्रिक्स गुणन और विभाजन; MATLAB और कई सरणी प्रोग्रामिंग भाषाओं में रैखिक प्रणालियों को हल करना ("C = B / A; x = A \ b")
  • नियमित अभिव्यक्ति
  • चर-लंबाई सरणियाँ - विशेष रूप से, सरणी के अंत में एक आइटम को जोड़ना, जिसमें (कभी-कभी) अधिक मेमोरी आवंटित करने की आवश्यकता होती है।
  • चरों का मान पढ़ना जो रनटाइम के समय बदलते हैं - कभी-कभी यह एक फ्लोट होता है, दूसरी बार यह एक स्ट्रिंग है
  • साहचर्य सरणियों (अक्सर "मानचित्र" या "शब्दकोश") कहा जाता है
  • सूचियों
  • अनुपात ("(+ 1/3 2/7)" लिस्प में "13/21" देता है )
  • मनमाना-सटीक अंकगणित (जिसे अक्सर "बिग्नम" कहा जाता है)
  • एक मुद्रण योग्य प्रतिनिधित्व में डेटा परिवर्तित करना (जावास्क्रिप्ट में ".tostring" विधि)
  • नियत-बिंदु संख्याओं को संतृप्त करना (अक्सर एम्बेडेड सी कार्यक्रमों में उपयोग किया जाता है)
  • रन टाइम में टाइप किए गए स्ट्रिंग का मूल्यांकन करना हालांकि यह एक अभिव्यक्ति थी (कई प्रोग्रामिंग भाषाओं में "eval ()")।

इन सभी कार्यों के लिए मशीन-भाषा के दर्जनों निर्देशों की आवश्यकता होती है या लगभग हर प्रोसेसर पर कुछ रनटाइम लूप की पुनरावृति की आवश्यकता होती है।

कुछ लोकप्रिय नियंत्रण संरचनाओं में दर्जनों मशीन-भाषा निर्देशों या लूपिंग की भी आवश्यकता होती है:

  • बंद
  • निरंतरता
  • अपवाद
  • आलसी मूल्यांकन

चाहे सी या किसी अन्य भाषा में लिखा गया हो, जब कोई प्रोग्राम इस तरह के डेटा प्रकारों में हेरफेर करता है, तो सीपीयू को अंततः उन डेटा प्रकारों में हेरफेर करने के लिए जो भी निर्देश की आवश्यकता होती है उसे निष्पादित करना चाहिए। वे निर्देश अक्सर "पुस्तकालय" में निहित होते हैं। प्रत्येक प्रोग्रामिंग भाषा, यहां तक ​​कि सी, में प्रत्येक मंच के लिए एक "रन-टाइम लाइब्रेरी" होती है जो हर निष्पादन योग्य में डिफ़ॉल्ट रूप से शामिल होती है।

ज्यादातर लोग जो कम्पाइलर लिखते हैं, वे उन सभी डेटा प्रकारों में हेरफेर करने के निर्देश देते हैं जो "भाषा में निर्मित होते हैं" उनके रन-टाइम लाइब्रेरी में। सी नहीं है क्योंकि किसी भी जो सी चलाने के समय पुस्तकालय रन की तुलना में छोटे बनाता है - ऊपर डेटा प्रकार और संचालन और नियंत्रण संरचनाओं में भाषा, उनमें से कोई सी चलाने के समय पुस्तकालय में शामिल किए गए हैं बनाया का अन्य प्रोग्रामिंग भाषाओं का समय पुस्तकालय जिसमें निर्मित सामानों की अधिकता भाषा में है।

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


यदि आपका लिस्प का कार्यान्वयन 3/21 के रूप में (+ 1/3 2/7) का मूल्यांकन करता है, तो मुझे लगता है कि आपके पास विशेष रूप से रचनात्मक कार्यान्वयन होना चाहिए ...
रॉबर्ट बी

4

अंतर्निहित डेटा प्रकार क्या हैं C? वे तरह बातें कर रहे हैं int, char, * int, float, सरणियों आदि ... ये डेटा प्रकार सीपीयू द्वारा समझ रहे हैं। सीपीयू जानता है कि सरणियों के साथ कैसे काम किया जाए, बिंदुओं को कैसे कम किया जाए और पॉइंटर्स, पूर्णांकों और फ्लोटिंग पॉइंट नंबरों पर अंकगणित कैसे किया जाए।

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


2
x86 कुछ सरणियों के साथ काम करना जानता है, लेकिन सभी नहीं। बड़े या असामान्य तत्व आकारों के लिए, एक सरणी सूचकांक को सूचक ऑफसेट में बदलने के लिए पूर्णांक अंकगणितीय प्रदर्शन करना होगा। और अन्य प्लेटफार्मों पर, यह हमेशा की जरूरत है। और यह विचार कि सीपीयू C ++ क्लासेस को नहीं समझता है, हँसने योग्य है। यह सिर्फ सी ऑफर्स की तरह पॉइंटर ऑफसेट है। उसके लिए आपको रनटाइम की जरूरत नहीं है।
MSalters

@MSalters हाँ, लेकिन मानक पुस्तकालय वर्गों की वास्तविक विधियाँ जैसे iostreams आदि संकलक द्वारा सीधे समर्थित होने के बजाय पुस्तकालय के कार्य हैं। हालाँकि, उच्च स्तर की भाषाएं जिनकी वे तुलना कर रहे थे, वे C ++ नहीं थीं, लेकिन समकालीन भाषाएँ जैसे कि FORTRAN और PL / I।
रैंडम 832

1
वर्चुअल सदस्य फ़ंक्शंस के साथ C ++ कक्षाएं एक संरचना में केवल एक ऑफसेट की तुलना में बहुत अधिक में अनुवाद करती हैं।
पीटर कॉर्ड्स

4

यह कंप्यूटर पर निर्भर करता है। पीडीपी -11 पर, जहां सी का आविष्कार किया गया था, longखराब समर्थन किया गया था (एक वैकल्पिक ऐड-ऑन मॉड्यूल था जिसे आप खरीद सकते थे कुछ समर्थित, लेकिन सभी नहीं, 32-बिट संचालन)। मूल आईबीएम पीसी सहित किसी भी 16-बिट सिस्टम पर विभिन्न डिग्री के लिए भी यही सच है। और इसी तरह 32-बिट मशीनों पर या 32-बिट कार्यक्रमों में 64-बिट संचालन के लिए, हालांकि K & R पुस्तक के समय C भाषा में 64-बिट ऑपरेशन बिल्कुल भी नहीं थे। और निश्चित रूप से 80 और 90 के दशक में [386 और कुछ 486 प्रोसेसर सहित) कई प्रणालियां हैं, और आज भी कुछ एम्बेडेड सिस्टम हैं, जो फ्लोटिंग पॉइंट अंकगणितीय ( floatया double) का सीधे समर्थन नहीं करते हैं ।

अधिक विदेशी उदाहरण के लिए, कुछ कंप्यूटर आर्किटेक्चर केवल "वर्ड-ओरिएंटेड" पॉइंटर्स (मेमोरी में दो-बाइट या चार-बाइट पूर्णांक पर इंगित करते हुए) का समर्थन करते हैं, और बाइट पॉइंटर्स ( char *या void *) को एक अतिरिक्त ऑफसेट फ़ील्ड जोड़कर लागू किया जाना था। यह प्रश्न ऐसी प्रणालियों के बारे में कुछ विस्तार से बताता है।

"क्रम पुस्तकालय" कार्यों यह दर्शाता है जिन्हें आप के मैनुअल में देखेंगे नहीं हैं, लेकिन जैसे कार्यों के इन, एक आधुनिक संकलक के क्रम पुस्तकालय में है, जो कि कर रहे हैं बुनियादी प्रकार के संचालन को लागू करने के लिए उपयोग किया जाता नहीं मशीन द्वारा समर्थित । रनटाइम लाइब्रेरी जिसे K & R खुद संदर्भित कर रहे थे , उसे यूनिक्स हेरिटेज सोसाइटी की वेबसाइट पर पाया जा सकता है - आप कार्यों को देख सकते हैं ldiv(उसी नाम के C फ़ंक्शन से अलग, जो उस समय मौजूद नहीं था) जिसका उपयोग पीढ़ी के विभाजन को लागू करने के लिए किया जाता है 32-बिट मान, जो PDP-11 ऐड-ऑन के साथ भी समर्थन नहीं करता था, और csv(और cretcsv.c में भी) जो फ़ंक्शन को कॉल और रिटर्न को प्रबंधित करने के लिए स्टैक पर रजिस्टरों को सहेजता और पुनर्स्थापित करता है।

वे संभावित रूप से अंतर्निहित डेटा द्वारा समर्थित कई डेटा प्रकारों का समर्थन नहीं करने की बात कर रहे थे, जो कि फ़ोरट्रान जैसी अन्य समकालीन भाषाओं के विपरीत अंतर्निहित मशीन द्वारा समर्थित नहीं थे, जिसमें सरणी शब्दार्थ था जो मैप के साथ-साथ सीपीयू के अंतर्निहित पॉइंटर समर्थन का भी समर्थन नहीं करता था। सी की गिरफ्तारी। तथ्य यह है कि सी सरणियाँ हमेशा शून्य-अनुक्रमित होती हैं और हमेशा सभी रैंकों में ज्ञात आकार की होती हैं, लेकिन पहले का अर्थ है कि अनुक्रमणिका श्रेणियों या सरणियों के आकार को संग्रहीत करने की कोई आवश्यकता नहीं है, और उन्हें एक्सेस करने के लिए रनटाइम लाइब्रेरी फ़ंक्शन की आवश्यकता नहीं है - संकलक केवल आवश्यक सूचक अंकगणित को हार्डकोड कर सकता है।


3

कथन का सीधा मतलब है कि C में डेटा और नियंत्रण संरचनाएं मशीन-उन्मुख हैं।

यहाँ पर विचार करने के दो पहलू हैं। एक यह है कि सी भाषा में एक परिभाषा (आईएसओ मानक) है जो डेटा प्रकारों को परिभाषित करने में अक्षांश की अनुमति देता है। इसका मतलब है कि सी भाषा कार्यान्वयन मशीन के अनुरूप हैं । C कंपाइलर के डेटा प्रकार मिलान मशीन में उपलब्ध है जो संकलक को लक्षित करता है, क्योंकि भाषा में इसके लिए अक्षांश है। यदि एक मशीन में 36 बिट्स की तरह एक असामान्य शब्द आकार है, तो उस प्रकार के अनुरूप intया longइसे बनाया जा सकता है। प्रोग्राम जो मानते हैं कि intवास्तव में 32 बिट्स टूटेंगे।

दूसरी बात यह है कि इस तरह की पोर्टेबिलिटी की समस्या के कारण दूसरा प्रभाव पड़ता है। एक तरह से, के एंड आर में बयान स्व-पूर्ति की भविष्यवाणी का एक प्रकार बन गया है , या शायद रिवर्स में। कहने का तात्पर्य यह है कि, नए प्रोसेसरों के कार्यान्वयनकर्ताओं को सी कंपाइलरों का समर्थन करने की गहरी आवश्यकता के बारे में पता है, और वे जानते हैं कि बहुत सारे सी कोड मौजूद हैं जो मानते हैं कि "प्रत्येक प्रोसेसर 80386 जैसा दिखता है"। आर्किटेक्चर को सी को ध्यान में रखकर डिजाइन किया गया है: और न केवल सी को ध्यान में रखते हुए, बल्कि सी पोर्टेबिलिटी के बारे में भी आम गलतफहमियों के साथ। आप बस 9 बिट बाइट्स या सामान्य प्रयोजन के लिए जो कुछ भी उपयोग करते हैं उसके साथ एक मशीन को पेश नहीं कर सकते। प्रोग्राम जो मानते हैं कि प्रकारcharहै बिल्कुल 8 बिट चौड़ा टूट जाएगा। पोर्टेबिलिटी विशेषज्ञों द्वारा लिखे गए केवल कुछ कार्यक्रम काम करना जारी रखेंगे: संभवत: उचित प्रयास के साथ टूलकिन, कर्नेल, उपयोगकर्ता स्थान और उपयोगी अनुप्रयोगों के साथ एक पूरी प्रणाली को एक साथ खींचने के लिए पर्याप्त नहीं है। दूसरे शब्दों में, C प्रकार हार्डवेयर से उपलब्ध है जैसे दिखते हैं क्योंकि हार्डवेयर को कुछ अन्य हार्डवेयर की तरह देखने के लिए बनाया गया था जिसके लिए कई गैर-सी C प्रोग्राम लिखे गए थे।

क्या एक डेटा प्रकार या एक नियंत्रण संरचना का एक उदाहरण है जो सीधे कंप्यूटर द्वारा समर्थित नहीं है?

कई मशीन भाषाओं में डेटा प्रकार सीधे समर्थित नहीं हैं: बहु-सटीक पूर्णांक; लिंक्ड सूची; हैश टेबल; वर्ण स्ट्रिंग।

अधिकांश मशीन भाषाओं में सीधे नियंत्रण संरचनाएं समर्थित नहीं हैं: प्रथम श्रेणी की निरंतरता; coroutine / धागा; जनरेटर; उपवाद सम्भालना।

इन सभी को कई सामान्य उद्देश्य निर्देशों और अधिक प्राथमिक डेटा प्रकारों का उपयोग करके बनाए गए रन-टाइम सपोर्ट कोड की आवश्यकता होती है।

C में कुछ मानक डेटा प्रकार हैं जो कुछ मशीनों द्वारा समर्थित नहीं हैं। C99 के बाद से C में जटिल संख्याएँ हैं। वे दो फ्लोटिंग-पॉइंट वैल्यू से बने होते हैं और लाइब्रेरी रूटीन के साथ काम करने के लिए बनाए जाते हैं। कुछ मशीनों में फ्लोटिंग-पॉइंट यूनिट बिल्कुल नहीं होती है।

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

इसके अलावा, फ़्लोटिंग-पॉइंट की बात करते हुए, मानकीकरण है: IEEE 754 फ़्लोटिंग-पॉइंट। आपके सी कंपाइलर में ऐसा क्यों है, doubleजो प्रोसेसर द्वारा समर्थित फ्लोटिंग-पॉइंट फॉर्मेट से सहमत है, केवल इसलिए नहीं कि दोनों को सहमत करने के लिए बनाया गया था, बल्कि इसलिए कि उस प्रतिनिधित्व के लिए एक स्वतंत्र मानक है।


2

ऐसी बातें

  • लगभग सभी कार्यात्मक भाषाओं में प्रयुक्त सूचियाँ

  • अपवाद

  • सहयोगी सरणियाँ (मैप्स) - जैसे PHP और पर्ल शामिल हैं।

  • कचरा संग्रह

  • डेटा प्रकार / नियंत्रण संरचना कई भाषाओं में शामिल हैं, लेकिन सीपीयू द्वारा सीधे समर्थित नहीं हैं।


2

सीधे समर्थित को प्रोसेसर के निर्देश सेट में कुशलता से मैपिंग के रूप में समझा जाना चाहिए।

  • पूर्णांक प्रकारों के लिए प्रत्यक्ष समर्थन नियम है, लंबे समय को छोड़कर (विस्तारित अंकगणित दिनचर्या की आवश्यकता हो सकती है) और छोटे आकार (मास्किंग की आवश्यकता हो सकती है)।

  • फ्लोटिंग-पॉइंट प्रकारों के लिए प्रत्यक्ष समर्थन के लिए एक FPU की आवश्यकता होती है।

  • बिट क्षेत्रों के लिए प्रत्यक्ष समर्थन असाधारण है।

  • संरचना और सरणियों को पते की गणना की आवश्यकता होती है, सीधे कुछ हद तक समर्थित होती है।

  • सूचक हमेशा अप्रत्यक्ष रूप से संबोधित के माध्यम से सीधे समर्थित होते हैं।

  • गोटो / अगर / जबकि / के लिए / बिना शर्त / सशर्त शाखाओं द्वारा सीधे समर्थन किया जाता है।

  • जब जंप टेबल लागू होती है तो स्विच को सीधे समर्थन दिया जा सकता है।

  • स्टैक सुविधाओं के माध्यम से फ़ंक्शन कॉल सीधे समर्थित हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.