संकलन समय पर 1 + 2 + 3 +… + 1000 की गणना करने के लिए C #, C ++ या जावा कंपाइलर कैसे चलाएं?


122

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

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


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

C ++ में मेटा-प्रोग्रामिंग के बारे में एक अच्छी किताब यह है । रुचि लेने के लिए एक नज़र रखना।

एक उपयोगी C ++ मेटा-प्रोग्रामिंग लाइब्रेरी इस लिंक का बूस्ट एमपीएल है ।


17
#error "500500" एक संकलन त्रुटि "पूर्णता" के रूप में गिना जाता है?
रहस्यमयी

4
संकेत अनिवार्य रूप से आपके लिए C ++ टेम्पलेट का उपयोग करने का मतलब है। स्पष्ट रूप से ऐसा नहीं है, लेकिन यह एक 1 से 1000 के मुद्रण के लिए है, मुझे यकीन है कि आप इसे एक हजार में जोड़ने के लिए संशोधित कर सकते हैं ... stackoverflow.com/questions/4568645/…
जो

8
const int value = 1 + 2 + 3.... + 1000; Console.WriteLine(value);; पी
जॉर्ज डकेट

8
कभी-कभी मुझे लगता है कि साक्षात्कारकर्ता की बौद्धिक श्रेष्ठता को साबित करने के लिए कुछ साक्षात्कार प्रश्न पूछे जाते हैं।
क्रिस ड्वायर

4
क्या आपके द्वारा यह प्रश्न पूछे जाने से पहले आपने बहुत पैसे मांगे थे?
सलमान ए

जवाबों:


118

अद्यतन सुधार की गहराई के साथ अब अपडेट किया गया ! MSVC10 और GCC पर गहराई के बिना काम करता है। :)


सरल संकलन-समय पुनरावर्तन + जोड़:

template<unsigned Cur, unsigned Goal>
struct adder{
  static unsigned const sub_goal = (Cur + Goal) / 2;
  static unsigned const tmp = adder<Cur, sub_goal>::value;
  static unsigned const value = tmp + adder<sub_goal+1, Goal>::value;
};

template<unsigned Goal>
struct adder<Goal, Goal>{
  static unsigned const value = Goal;
};

Testcode:

template<unsigned Start>
struct sum_from{
  template<unsigned Goal>
  struct to{
    template<unsigned N>
    struct equals;

    typedef equals<adder<Start, Goal>::value> result;
  };
};

int main(){
  sum_from<1>::to<1000>::result();
}

जीसीसी के लिए आउटपुट:

त्रुटि: 'संरचना sum_from <1u> :: का <1000u> :: समतुल्य <500500u> की घोषणा

आइडोन पर लाइव उदाहरण

MSVC10 के लिए आउटपुट:

error C2514: 'sum_from<Start>::to<Goal>::equals<Result>' : class has no constructors
      with
      [
          Start=1,
          Goal=1000,
          Result=500500
      ]

@salimi: मैंने वास्तव में कुछ कोड दिखाने के लिए जवाब संपादित किया जो काम करता है। :)
Xeo

वाह, आपने मुझे बहुत प्रभावित किया :-)
गुप्ता

@salimi: यह डॉ। इरविन Unruh थे जिन्होंने स्टॉकहोम में 1997 C ++ मानकीकरण बैठक में इस तकनीक का आविष्कार किया था। उन्होंने अभाज्य संख्याओं की एक श्रृंखला की गणना की।
डायटमार कुहल

पुनरावृत्ति के बिना इसे काम करने के लिए आप योग की गणना करने के लिए N * (N + 1) / 2 के सूत्र का उपयोग कर सकते हैं।
एडम ग्रिट

2
@salimi अगर आप C ++ में टेम्पलेट मेटाप्रोग्रामिंग के बहुत अधिक शानदार उदाहरण देखना चाहते हैं, तो मैं आंद्रेई अलेक्जेंड्रेस्कू द्वारा मॉडर्न C ++ डिज़ाइन का सुझाव देता हूं ।
दारुकुक १२'१२ बजे

89

संकलन समय में त्रुटि के लिए C # उदाहरण।

class Foo
{
    const char Sum = (1000 + 1) * 1000 / 2;
}

निम्नलिखित संकलन त्रुटि उत्पन्न करता है:

Constant value '500500' cannot be converted to a 'char' 

4
@ildjarn खैर c ++ टेम्पलेट उत्तरों और इस एक के बीच एक अंतर है: यह केवल निरंतर तह की वजह से काम करता है जबकि टेम्पलेट मनमाना (?) कोड के लिए अनुमति देता है। अभी भी एक अच्छा विचार यह एक चार को आवंटित करने के लिए!
वू

@Voo हाँ, लेकिन निष्पक्ष होने के लिए C # इस तरह की प्रोग्रामिंग के लिए C ++ से तुलना नहीं करता है।
मार्लन

3
@ मैरियन और मैं वास्तव में इस बात पर विचार नहीं करता कि भाषा डिजाइन में एक गलती;) टेम्प्लेट मेटा प्रोग्रामिंग सभी शक्तिशाली हो सकती है, लेकिन अन्य भाषाएं अभी भी अन्य समाधानों के साथ अधिकांश काम कर सकती हैं जिनमें उन सभी नुकसान नहीं हैं। मुझे एक ऐसी परियोजना पर काम करना पड़ा है जिसमें संकलन करने में घंटों लग गए (पूरी तरह से सच नहीं है - यह अविश्वसनीय रूप से तेज़ था अगर हमने पुनरावर्ती तात्कालिकता सीमा नहीं बढ़ाई .. यह सेकंड में विफल रहा) और बनाए रखने के लिए भयानक था। शायद एक कारण है कि मैं इसका बहुत प्रशंसक नहीं हूं ..
वू

@Voo: फ्रेड ऑवरफ्लो का दृष्टिकोण निरंतर तह पर भी निर्भर करता है। जहाँ तक धीमे संकलन का सवाल है, अपने संकलक को दोष दें, भाषा को नहीं (संकेत - क्लैंग संकलन सी ++ तेज़ )।
०१:२५ बजे ildjarn

@ चिल्ड्रन क्लैंग बहुत जटिल, वास्तव में गहरी नेस्टेड और बुरी तरह से जटिल टेम्पलेट्स तेजी से संकलित करता है? मैं सब कुछ संभव मानता हूं और मैं अब इसका परीक्षण नहीं कर सकता (भगवान का शुक्र है) लेकिन मैं इसकी कल्पना नहीं कर सकता। इसके अलावा, मैं Xio के फ्रेड के यहाँ नहीं दृष्टिकोण के बारे में बात कर रहा हूँ।
वू

51

मुझे बस एक कार्यक्रम लिखना चाहिए जो संकलन करते समय इस राशि की गणना करने के लिए संकलक को ड्राइव कर सके और संकलन पूरा होने पर परिणाम प्रिंट कर सके।

संकलन के दौरान एक संख्या को प्रिंट करने की एक लोकप्रिय चाल, उस संख्या के एक गैर-मौजूद सदस्य तक पहुँचने की कोशिश कर रही है जिस संख्या को आप प्रिंट करना चाहते हैं:

template<int> struct print_n {};

print_n<1000 * 1001 / 2>::foobar go;

संकलक तब कहता है:

error: 'foobar' in 'struct print_n<500500>' does not name a type

इस तकनीक के अधिक दिलचस्प उदाहरण के लिए, संकलन-समय पर आठ रानियों की समस्या को हल करें देखें ।


तुम बस अस्वस्थ print_nरहने दो , मेरा जवाब देख सकते हैं।
Xeo

2
@ डेविड लेकिन गॉस को एक चतुर तरीके की आवश्यकता थी, उसके पास बेवकूफ तरीके से तेज करने के लिए कंप्यूटर नहीं था।
डैनियल फिशर

31

चूंकि साक्षात्कार प्रश्न में न तो संकलक और न ही भाषा निर्दिष्ट की गई थी, इसलिए मैंने GHC का उपयोग करके हास्केल में एक समाधान प्रस्तुत करने का साहस किया:

{-# LANGUAGE TemplateHaskell #-}
{-# OPTIONS_GHC -ddump-splices #-}
module Main where

main :: IO ()
main = print $(let x = sum [1 :: Int .. 1000] in [| x |])

इसे संकलित करें:

$ ghc compsum.hs
[1 of 1] Compiling Main             ( compsum.hs, compsum.o )
Loading package ghc-prim ... linking ... done.
<snip more "Loading package ..." messages>
Loading package template-haskell ... linking ... done.
compsum.hs:6:16-56: Splicing expression
    let x = sum [1 :: Int .. 1000] in [| x |] ======> 500500
Linking compsum ...

और हमें एक काम करने का कार्यक्रम भी मिला।


20

C ++ 11 के साथ जीवन बहुत आसान हो जाएगा, जो constexprसंकलन समय गणना के लिए फ़ंक्शन जोड़ता है , हालांकि वे केवल वर्तमान में gcc 4.6 या बाद में समर्थन करते हैं।

constexpr unsigned sum(unsigned start, unsigned end) {
    return start == end ? start :
        sum(start, (start + end) / 2) +
        sum((start + end) / 2 + 1, end);
}

template <int> struct equals;
equals<sum(1,1000)> x;

मानक को केवल 512 की पुनरावृत्ति गहराई का समर्थन करने के लिए कंपाइलर की आवश्यकता होती है, इसलिए इसे अभी भी रैखिक पुनरावृत्ति गहराई से बचने की आवश्यकता है। यहाँ उत्पादन है:

$ g++-mp-4.6 --std=c++0x test.cpp -c
test.cpp:8:25: error: aggregate 'equals<500500> x' has incomplete type and cannot be defined

बेशक आप सिर्फ सूत्र का उपयोग कर सकते हैं:

constexpr unsigned sum(unsigned start, unsigned end) {
    return (start + end) * (end - start + 1) / 2;
}

// static_assert is a C++11 assert, which checks
// at compile time.
static_assert(sum(0,1000) == 500500, "Sum failed for 0 to 1000");

1
+1, constexprएक पल के लिए पूरी तरह से भूल गया । हो सकता है कि मैं सिर्फ बहुत अधिक टेम्पलेट्स प्यार करता हूँ। :(
Xeo

प्रश्न को संबोधित करने के लिए कॉन्स्टेक्सप्र का यह एक अच्छा उपयोग है ( एडडर
मैट

वह सूत्र ओवरफ्लो हो सकता है; अंतिम चरण / 2संभव unsignedपरिणामों की पूरी श्रृंखला को संभालने के लिए है , जो मूल्य आप सही-स्थानांतरण कर रहे हैं वह n + 1 बिट्स चौड़ा होना चाहिए, लेकिन यह नहीं है। इससे बचने के लिए सूत्र को पुनर्व्यवस्थित करना संभव है, जैसे क्लैंग रनटाइम-वैरिएबल पर्वतमाला के लिए करता है: Godbolt.org/z/dUGXqg दिखाता है कि क्लैंग क्लोज-फॉर्म फॉर्मूला को जानता है और total += iलूप्स को ऑप्टिमाइज़ करने के लिए इसका उपयोग करता है ।
पीटर कॉर्डेस

14

जावा में, मैंने एनोटेशन प्रोसेसिंग का उपयोग करने के बारे में सोचा। Apt उपकरण वास्तव में स्रोत फ़ाइल को javac कमांड पर पार्स करने से पहले स्रोत फ़ाइल को स्कैन करता है।

स्रोत फ़ाइलों के संकलन के दौरान, आउटपुट प्रिंट आउट किया जाएगा:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface MyInterface {

    int offset() default 0;

    int last() default 100;
}

प्रोसेसर कारखाना:

public class MyInterfaceAnnotationProcessorFactory implements AnnotationProcessorFactory {

    public Collection<String> supportedOptions() {
        System.err.println("Called supportedOptions.............................");
        return Collections.EMPTY_LIST;
    }

    public Collection<String> supportedAnnotationTypes() {
        System.err.println("Called supportedAnnotationTypes...........................");
        return Collections.singletonList("practiceproject.MyInterface");
    }

    public AnnotationProcessor getProcessorFor(Set<AnnotationTypeDeclaration> set, AnnotationProcessorEnvironment ape) {
        System.err.println("Called getProcessorFor................");
        if (set.isEmpty()) {
            return AnnotationProcessors.NO_OP;
        }
        return new MyInterfaceAnnotationProcessor(ape);
    }
}

वास्तविक एनोटेशन प्रोसेसर:

public class MyInterfaceAnnotationProcessor implements AnnotationProcessor {

    private AnnotationProcessorEnvironment ape;
    private AnnotationTypeDeclaration atd;

    public MyInterfaceAnnotationProcessor(AnnotationProcessorEnvironment ape) {
        this.ape = ape;
        atd = (AnnotationTypeDeclaration) ape.getTypeDeclaration("practiceproject.MyInterface");
    }

    public void process() {
        Collection<Declaration> decls = ape.getDeclarationsAnnotatedWith(atd);
        for (Declaration dec : decls) {
            processDeclaration(dec);
        }
    }

    private void processDeclaration(Declaration d) {
        Collection<AnnotationMirror> ams = d.getAnnotationMirrors();
        for (AnnotationMirror am : ams) {
            if (am.getAnnotationType().getDeclaration().equals(atd)) {
                Map<AnnotationTypeElementDeclaration, AnnotationValue> values = am.getElementValues();
                int offset = 0;
                int last = 100;
                for (Map.Entry<AnnotationTypeElementDeclaration, AnnotationValue> entry : values.entrySet()) {
                    AnnotationTypeElementDeclaration ated = entry.getKey();
                    AnnotationValue v = entry.getValue();
                    String name = ated.getSimpleName();
                    if (name.equals("offset")) {
                        offset = ((Integer) v.getValue()).intValue();
                    } else if (name.equals("last")) {
                        last = ((Integer) v.getValue()).intValue();
                    }
                }
                //find the sum
                System.err.println("Sum: " + ((last + 1 - offset) / 2) * (2 * offset + (last - offset)));
            }
        }
    }
}

फिर हम एक सोर्स फाइल बनाते हैं। सरल वर्ग जो MyInterface एनोटेशन का उपयोग करता है:

 @MyInterface(offset = 1, last = 1000)
public class Main {

    @MyInterface
    void doNothing() {
        System.out.println("Doing nothing");
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        Main m = new Main();
        m.doNothing();
        MyInterface my = (MyInterface) m.getClass().getAnnotation(MyInterface.class);
        System.out.println("offset: " + my.offset());
        System.out.println("Last: " + my.last());
    }
}

एनोटेशन प्रोसेसर को जार फ़ाइल में संकलित किया जाता है, फिर उपयुक्त टूल का उपयोग स्रोत फ़ाइल को संकलित करने के लिए किया जाता है:

apt -cp "D:\Variance project\PracticeProject\dist\practiceproject.jar" -factory practiceproject.annotprocess.MyInterfaceAnnotationProcessorFactory "D:\Variance project\PracticeProject2\src\practiceproject2\Main.java"

परियोजना का उत्पादन:

Called supportedAnnotationTypes...........................
Called getProcessorFor................
Sum: 5000
Sum: 500500

9

यहाँ एक कार्यान्वयन है जो VC ++ 2010 के तहत काम करता है। मुझे कंपाइलर द्वारा शिकायत किए जाने के बाद से 3 चरणों में गणना को तोड़ना पड़ा, जब टेम्प्लेट 500+ बार पुन: प्राप्त हुए।

template<int t_startVal, int t_baseVal = 0, int t_result = 0>
struct SumT
{
    enum { result = SumT<t_startVal - 1, t_baseVal, t_baseVal + t_result +
        t_startVal>::result };
};

template<int t_baseVal, int t_result>
struct SumT<0, t_baseVal, t_result>
{
    enum { result = t_result };
};

template<int output_value>
struct Dump
{
    enum { value = output_value };
    int bad_array[0];
};

enum
{
    value1 = SumT<400>::result,                // [1,400]
    value2 = SumT<400, 400, value1>::result,   // [401, 800]
    value3 = SumT<200, 800, value2>::result    // [801, 1000]
};

Dump<value3> dump;

जब आप इसे संकलित करते हैं, तो आपको इस आउटपुट को संकलक से कुछ इस तरह देखना चाहिए:

1>warning C4200: nonstandard extension used : zero-sized array in struct/union
1>          Cannot generate copy-ctor or copy-assignment operator when UDT contains a 
zero-sized array
1>          templatedrivensum.cpp(33) : see reference to class template 
instantiation 'Dump<output_value>' being compiled
1>          with
1>          [
1>              output_value=500500
1>          ]

इसे तोड़ने के साथ बहुत अच्छा विचार है, मुझे लगता है कि मैं किसी भी तरह अपने जवाब में शामिल करने वाला हूं। +1 :)
Xeo

9

मैं इस सी कोड को देने के लिए बाध्य महसूस करता हूं, क्योंकि किसी और के पास अभी तक नहीं है:

#include <stdio.h>
int main() {
   int x = 1+2+3+4+5+6+7+8+9+10+11+12+13+14+15+16+17+18+19+20+
           21+22+23+24+25+26+27+28+29+30+31+32+33+34+35+36+37+38+39+40+
           41+42+43+44+45+46+47+48+49+50+51+52+53+54+55+56+57+58+59+60+
           61+62+63+64+65+66+67+68+69+70+71+72+73+74+75+76+77+78+79+80+
           81+82+83+84+85+86+87+88+89+90+91+92+93+94+95+96+97+98+99+100+     
           101+102+103+104+105+106+107+108+109+110+111+112+113+114+115+116+117+118+119+120+
           121+122+123+124+125+126+127+128+129+130+131+132+133+134+135+136+137+138+139+140+
           141+142+143+144+145+146+147+148+149+150+151+152+153+154+155+156+157+158+159+160+
           161+162+163+164+165+166+167+168+169+170+171+172+173+174+175+176+177+178+179+180+
           181+182+183+184+185+186+187+188+189+190+191+192+193+194+195+196+197+198+199+200+
           201+202+203+204+205+206+207+208+209+210+211+212+213+214+215+216+217+218+219+220+
           221+222+223+224+225+226+227+228+229+230+231+232+233+234+235+236+237+238+239+240+
           241+242+243+244+245+246+247+248+249+250+251+252+253+254+255+256+257+258+259+260+
           261+262+263+264+265+266+267+268+269+270+271+272+273+274+275+276+277+278+279+280+
           281+282+283+284+285+286+287+288+289+290+291+292+293+294+295+296+297+298+299+300+
           301+302+303+304+305+306+307+308+309+310+311+312+313+314+315+316+317+318+319+320+
           321+322+323+324+325+326+327+328+329+330+331+332+333+334+335+336+337+338+339+340+
           341+342+343+344+345+346+347+348+349+350+351+352+353+354+355+356+357+358+359+360+
           361+362+363+364+365+366+367+368+369+370+371+372+373+374+375+376+377+378+379+380+
           381+382+383+384+385+386+387+388+389+390+391+392+393+394+395+396+397+398+399+400+
           401+402+403+404+405+406+407+408+409+410+411+412+413+414+415+416+417+418+419+420+
           421+422+423+424+425+426+427+428+429+430+431+432+433+434+435+436+437+438+439+440+
           441+442+443+444+445+446+447+448+449+450+451+452+453+454+455+456+457+458+459+460+
           461+462+463+464+465+466+467+468+469+470+471+472+473+474+475+476+477+478+479+480+
           481+482+483+484+485+486+487+488+489+490+491+492+493+494+495+496+497+498+499+500+
           501+502+503+504+505+506+507+508+509+510+511+512+513+514+515+516+517+518+519+520+
           521+522+523+524+525+526+527+528+529+530+531+532+533+534+535+536+537+538+539+540+
           541+542+543+544+545+546+547+548+549+550+551+552+553+554+555+556+557+558+559+560+
           561+562+563+564+565+566+567+568+569+570+571+572+573+574+575+576+577+578+579+580+
           581+582+583+584+585+586+587+588+589+590+591+592+593+594+595+596+597+598+599+600+
           601+602+603+604+605+606+607+608+609+610+611+612+613+614+615+616+617+618+619+620+
           621+622+623+624+625+626+627+628+629+630+631+632+633+634+635+636+637+638+639+640+
           641+642+643+644+645+646+647+648+649+650+651+652+653+654+655+656+657+658+659+660+
           661+662+663+664+665+666+667+668+669+670+671+672+673+674+675+676+677+678+679+680+
           681+682+683+684+685+686+687+688+689+690+691+692+693+694+695+696+697+698+699+700+
           701+702+703+704+705+706+707+708+709+710+711+712+713+714+715+716+717+718+719+720+
           721+722+723+724+725+726+727+728+729+730+731+732+733+734+735+736+737+738+739+740+
           741+742+743+744+745+746+747+748+749+750+751+752+753+754+755+756+757+758+759+760+
           761+762+763+764+765+766+767+768+769+770+771+772+773+774+775+776+777+778+779+780+
           781+782+783+784+785+786+787+788+789+790+791+792+793+794+795+796+797+798+799+800+
           801+802+803+804+805+806+807+808+809+810+811+812+813+814+815+816+817+818+819+820+
           821+822+823+824+825+826+827+828+829+830+831+832+833+834+835+836+837+838+839+840+
           841+842+843+844+845+846+847+848+849+850+851+852+853+854+855+856+857+858+859+860+
           861+862+863+864+865+866+867+868+869+870+871+872+873+874+875+876+877+878+879+880+
           881+882+883+884+885+886+887+888+889+890+891+892+893+894+895+896+897+898+899+900+
           901+902+903+904+905+906+907+908+909+910+911+912+913+914+915+916+917+918+919+920+
           921+922+923+924+925+926+927+928+929+930+931+932+933+934+935+936+937+938+939+940+
           941+942+943+944+945+946+947+948+949+950+951+952+953+954+955+956+957+958+959+960+
           961+962+963+964+965+966+967+968+969+970+971+972+973+974+975+976+977+978+979+980+
           981+982+983+984+985+986+987+988+989+990+991+992+993+994+995+996+997+998+999+1000;
  printf("%d\n", x);
}

और मुझे अपना उत्तर खोजने के लिए विधानसभा की जाँच करने की आवश्यकता है!

gcc -S compile_sum.c;
grep "\$[0-9]*, *-4" compile_sum.s

और मैं देख रहा हूँ:

movl    $500500, -4(%rbp)

एक विशिष्ट कार्यान्वयन की सुविधा, सी भाषा नहीं।
पिल्ला

5
आप कितने सी संकलक जानते हैं कि सी का "विशिष्ट कार्यान्वयन" नहीं है?
कार्ल वॉल्श

@Puppy: यदि xवैश्विक था, संकलन समय पर अभिव्यक्ति का मूल्यांकन करने के लिए संकलक (अधिक या कम) होगा। ISO C ग्लोबल्स के लिए रनटाइम-वैरिएबल इनिशियलाइज़र की अनुमति नहीं देता है। बेशक एक विशिष्ट कार्यान्वयन एक रचनाकार की तरह एक कॉल-इन-फंक्शन फ़ंक्शन का उत्सर्जन कर सकता है जो रनटाइम और स्टोर पर इसकी गणना करता है। लेकिन आईएसओ सी आपको संकलन समय स्थिरांक का उपयोग सरणी आकार (जैसे int y[x];एक संरचनात्मक परिभाषा में या उदाहरण के लिए एक अन्य वैश्विक) के रूप में करने देता है, इसलिए किसी भी काल्पनिक निराशावादी कार्यान्वयन को अभी भी समर्थन करना होगा।
पीटर कॉर्डेस

7

कार्ल वाल्श के जवाब से विस्तारित वास्तव में संकलन के दौरान परिणाम प्रिंट करें:

#define VALUE (1+2+3+4+5+6+7+8+9+10+11+12+13+14+15+16+17+18+19+20+\
21+22+23+24+25+26+27+28+29+30+31+32+33+34+35+36+37+38+39+40+\
41+42+43+44+45+46+47+48+49+50+51+52+53+54+55+56+57+58+59+60+\
61+62+63+64+65+66+67+68+69+70+71+72+73+74+75+76+77+78+79+80+\
81+82+83+84+85+86+87+88+89+90+91+92+93+94+95+96+97+98+99+100+\
101+102+103+104+105+106+107+108+109+110+111+112+113+114+115+116+117+118+119+120+\
121+122+123+124+125+126+127+128+129+130+131+132+133+134+135+136+137+138+139+140+\
141+142+143+144+145+146+147+148+149+150+151+152+153+154+155+156+157+158+159+160+\
161+162+163+164+165+166+167+168+169+170+171+172+173+174+175+176+177+178+179+180+\
181+182+183+184+185+186+187+188+189+190+191+192+193+194+195+196+197+198+199+200+\
201+202+203+204+205+206+207+208+209+210+211+212+213+214+215+216+217+218+219+220+\
221+222+223+224+225+226+227+228+229+230+231+232+233+234+235+236+237+238+239+240+\
241+242+243+244+245+246+247+248+249+250+251+252+253+254+255+256+257+258+259+260+\
261+262+263+264+265+266+267+268+269+270+271+272+273+274+275+276+277+278+279+280+\
281+282+283+284+285+286+287+288+289+290+291+292+293+294+295+296+297+298+299+300+\
301+302+303+304+305+306+307+308+309+310+311+312+313+314+315+316+317+318+319+320+\
321+322+323+324+325+326+327+328+329+330+331+332+333+334+335+336+337+338+339+340+\
341+342+343+344+345+346+347+348+349+350+351+352+353+354+355+356+357+358+359+360+\
361+362+363+364+365+366+367+368+369+370+371+372+373+374+375+376+377+378+379+380+\
381+382+383+384+385+386+387+388+389+390+391+392+393+394+395+396+397+398+399+400+\
401+402+403+404+405+406+407+408+409+410+411+412+413+414+415+416+417+418+419+420+\
421+422+423+424+425+426+427+428+429+430+431+432+433+434+435+436+437+438+439+440+\
441+442+443+444+445+446+447+448+449+450+451+452+453+454+455+456+457+458+459+460+\
461+462+463+464+465+466+467+468+469+470+471+472+473+474+475+476+477+478+479+480+\
481+482+483+484+485+486+487+488+489+490+491+492+493+494+495+496+497+498+499+500+\
501+502+503+504+505+506+507+508+509+510+511+512+513+514+515+516+517+518+519+520+\
521+522+523+524+525+526+527+528+529+530+531+532+533+534+535+536+537+538+539+540+\
541+542+543+544+545+546+547+548+549+550+551+552+553+554+555+556+557+558+559+560+\
561+562+563+564+565+566+567+568+569+570+571+572+573+574+575+576+577+578+579+580+\
581+582+583+584+585+586+587+588+589+590+591+592+593+594+595+596+597+598+599+600+\
601+602+603+604+605+606+607+608+609+610+611+612+613+614+615+616+617+618+619+620+\
621+622+623+624+625+626+627+628+629+630+631+632+633+634+635+636+637+638+639+640+\
641+642+643+644+645+646+647+648+649+650+651+652+653+654+655+656+657+658+659+660+\
661+662+663+664+665+666+667+668+669+670+671+672+673+674+675+676+677+678+679+680+\
681+682+683+684+685+686+687+688+689+690+691+692+693+694+695+696+697+698+699+700+\
701+702+703+704+705+706+707+708+709+710+711+712+713+714+715+716+717+718+719+720+\
721+722+723+724+725+726+727+728+729+730+731+732+733+734+735+736+737+738+739+740+\
741+742+743+744+745+746+747+748+749+750+751+752+753+754+755+756+757+758+759+760+\
761+762+763+764+765+766+767+768+769+770+771+772+773+774+775+776+777+778+779+780+\
781+782+783+784+785+786+787+788+789+790+791+792+793+794+795+796+797+798+799+800+\
801+802+803+804+805+806+807+808+809+810+811+812+813+814+815+816+817+818+819+820+\
821+822+823+824+825+826+827+828+829+830+831+832+833+834+835+836+837+838+839+840+\
841+842+843+844+845+846+847+848+849+850+851+852+853+854+855+856+857+858+859+860+\
861+862+863+864+865+866+867+868+869+870+871+872+873+874+875+876+877+878+879+880+\
881+882+883+884+885+886+887+888+889+890+891+892+893+894+895+896+897+898+899+900+\
901+902+903+904+905+906+907+908+909+910+911+912+913+914+915+916+917+918+919+920+\
921+922+923+924+925+926+927+928+929+930+931+932+933+934+935+936+937+938+939+940+\
941+942+943+944+945+946+947+948+949+950+951+952+953+954+955+956+957+958+959+960+\
961+962+963+964+965+966+967+968+969+970+971+972+973+974+975+976+977+978+979+980+\
981+982+983+984+985+986+987+988+989+990+991+992+993+994+995+996+997+998+999+1000)

char tab[VALUE];

int main()
{
    tab = 5;
}

जीसीसी आउटपुट:

test.c: In function 'main':
test.c:56:9: error: incompatible types when assigning to type 'char[500500]' fro
m type 'int'

2

आप मेटाप्रोग्रामिंग करने के लिए (और अधिकतर दुरुपयोग) सी ++ मैक्रो / टेम्प्लेट का उपयोग कर सकते हैं । AFAIK, Java एक ही तरह की चीज़ की अनुमति नहीं देता है।


2
वास्तव में सवाल का जवाब नहीं।
इके

मेरे विचार से आप सही है। जावा में आप समान टेम्प्लेट रिकर्सन ट्रिक का उपयोग नहीं कर सकते हैं, क्योंकि जेनेरिक क्लास पैरामीटर एक मान नहीं हो सकता है - यह एक क्लास होना चाहिए।
ईयाल श्नाइडर

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

1

सिद्धांत रूप में, आप इसका उपयोग कर सकते हैं:

#include <iostream>

template<int N>
struct Triangle{
  static int getVal()
  {
    return N + Triangle<N-1>::getVal();
  }
};

template<>
struct Triangle<1>{
  static int getVal()
  {
    return 1;
  }
};

int main(){
   std::cout << Triangle<1000>::getVal() << std::endl;
   return 0;
}

(उस कोड के आधार पर जिसे Xeo ने पोस्ट किया था)। लेकिन जीसीसी मुझे यह त्रुटि देता है:

triangle.c++:7: error: template instantiation depth exceeds maximum of 500 (use -ftemplate-depth-NN to increase the maximum) instantiating struct Triangle<500>

प्लस एक विशाल छद्म स्टैकट्रेस।


होगा झंडे का उपयोग करें: -ftemplate- गहराई-1000
जेटी

@ शालिमी: हाँ। एक बार झंडा जोड़ने पर यह 1000 के लिए भी काम करता है। लेकिन यह संकलन-समय पर नहीं छापता है , और Xeo ने वास्तव में इस विशिष्ट समस्या का जवाब देने के लिए अपना उत्तर बदल दिया है, इसलिए मुझे लगता है कि मेरा उत्तर अप्रचलित है। :-)
२३:२३

1

जावा का उपयोग करके आप C # उत्तर के समान काम कर सकते हैं:

public class Cheat {
    public static final int x = (1000 *1001/2);
}

javac -Xprint Cheat.java

public class Cheat {

  public Cheat();
  public static final int x = 500500;
}

आप पीनो नंबरों का उपयोग करके स्कैला में ऐसा कर सकते हैं क्योंकि आप कंपाइलर को पुनरावृत्ति करने के लिए मजबूर कर सकते हैं, लेकिन मुझे नहीं लगता कि आप सी # / जावा में एक ही काम कर सकते हैं

एक और समाधान -Xprint का उपयोग नहीं कर रहा है, लेकिन इससे भी ज्यादा डोडी

public class Cheat {
  public static final int x = 5/(1000 *1001/2 - 500500);
}

javac -Xlint:all Cheat.java

Cheat.java:2: warning: [divzero] division by zero
  public static final int x = 5/(1000 *1001/2 - 500500);
                            ^
1 warning

किसी भी संकलक झंडे का उपयोग किए बिना। चूंकि आप स्थिरांक की निरंतर संख्या की जांच कर सकते हैं (केवल 500500 नहीं) यह समाधान स्वीकार्य होना चाहिए।

public class Cheat {
  public static final short max = (Short.MAX_VALUE - 500500) + 1001*1000/2;
  public static final short overflow = (Short.MAX_VALUE - 500500 + 1) + 1001*1000/2;

}

Cheat.java:3: error: possible loss of precision
  public static final short overflow = (Short.MAX_VALUE - 500500 + 1) + 1001*1000/2;
                                                                  ^
  required: short
  found:    int
1 error

आपने कंपाइलर को गणना करने के लिए ड्राइव नहीं किया 500500, क्षमा करें।
Xio

1
क्या यह तीनों समाधानों के संदर्भ में है? समाधान 1 में मैंने कुछ जावा कोड लिए और इसे संकलित किया और कंपाइलर 500500 का प्रिंट आउट लिया। यह कंपाइलर 500500 की तरह दिखता है। यह कंपाइलर 500500 की गणना कैसे नहीं करता है?
बेन्मुर्फी

हाँ, बहुत सही है, मैं समाधान 2 और 3 के बारे में बात कर रहा था। मैंने पहले ही अपडेट पर इस जवाब को पढ़ा और सबसे नए पर वापस आया और किसी तरह पहला समाधान भूल गया लगता है।
Xeo

मैं कहूंगा कि समाधान 2 और 3 इसे भी कंप्यूटिंग कर रहे हैं। आप चेक की एक मनमानी संख्या जोड़ सकते हैं ताकि आप मूल रूप से कर रहे हैं for (i = 0; i < 100000; ++i) {if (i == 1000*1000/2) print i}। मैं एक 160mb जावा फ़ाइल है कि यह करता है और यह काम करता है :)
benmmurphy

1

हालाँकि यह वास्तव में छोटी संख्या के साथ काम करता है, अगर मैं sum_first जहां N> 400 का उपयोग कर रहा हूं, तो clang ++ मुझे एक संकलक त्रुटि देता है।

#include <iostream>

using namespace std;


template <int N>
struct sum_first
{
   static const int value = N + sum_first<N - 1>::value;
};

template <>
struct sum_first<0>
{
    static const int value = 0;
};

int main()
{
    cout << sum_first<1000>::value << endl;
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.