2010-04-16 8 views
18

संपादित के रूप में एक सरणी के साथ एक struct शुरु कर रहा है फिर से, क्योंकि यह मूल रूप से स्पष्ट है कि मैं संकलन समय पर सरणियों प्रारंभ करने, रन टाइम पर नहीं कोशिश कर रहा हूँ नहीं था ...C++ एक सदस्य


मैं

typedef struct TestStruct 
{ 
    int length; 
    int values[]; 
}; 

TestStruct t = {3, {0, 1, 2}}; 
TestStruct t2 = {4, {0, 1, 2, 3}}; 

int main() 
{ 
    return(0); 
} 

यह विज़ुअल सी ++ के साथ काम करता है, लेकिन लिनक्स के तहत ग्राम के साथ ++ संकलन नहीं करता है: 'निम्नलिखित कम testcase मिला लिया है। क्या कोई मुझे इस विशिष्ट प्रकार के प्रारंभिक पोर्टेबल बनाने में मदद कर सकता है?

अतिरिक्त विवरण: जिन वास्तविक संरचनाओं के साथ मैं काम कर रहा हूं उनमें कई अन्य int मान हैं, और सरणी एक प्रविष्टि से लंबाई 1800 प्रविष्टियों तक सीमित हो सकती है।

संपादित करें: मुझे लगता है (लेकिन मुझे यकीन नहीं है) कि यह एक वीएलए मुद्दा नहीं है। स्पष्टीकरण के लिए, मैं कंपाइलर को संकलन-समय पर मेरे लिए काम करने की कोशिश कर रहा हूं। रन-टाइम पर सरणी की लंबाई स्थिर है। क्षमा करें अगर मैं गलत हूं; मैं मुख्य रूप से एक सी #/पर्ल/रूबी प्रोग्रामर हूं जो इस विरासत ऐप को बनाए रखने में फंस गया है ...

किसी भी मदद की बहुत सराहना की। धन्यवाद!

+1

यह कानूनी सी ++ कोड नहीं है। सी ++ परिवर्तनीय-लंबाई सरणी या लचीली सरणी सदस्यों का समर्थन नहीं करता है। – rlbond

+0

दरअसल, यह जीसीसी में काम करता है - आपको अपने कोड में एक अप्रासंगिक त्रुटि मिली है, आप इसे 'टाइपेडफ' प्राप्त करने के बाद संरचना का नाम भूल गए हैं। हालांकि, आपने प्रश्न को सी ++ के रूप में टैग किया है - मुझे नहीं पता कि आप यह क्यों करेंगे। Typedeffing structs का उपयोग सी * (सी ++ के विपरीत) * की सीमा को दूर करने के लिए किया गया था, जहां यह आपको अनावश्यक 'स्ट्रक्चर' कीवर्ड के बिना एक स्ट्रक्चर चर घोषित करने की अनुमति नहीं देता था। –

उत्तर

18

सी ++ में सीएक्स के रूप में अंतिम तत्व के समान लचीला सरणी सदस्य नहीं है। यदि आपको नहीं पता कि आपको कितने तत्व हैं या आपको यह निर्दिष्ट करना चाहिए कि आप कितने हैं तो आपको std::vector का उपयोग करना चाहिए।

संपादित करें: आपने अपने संपादन में कहा है कि सरणी रनटाइम स्थिर है, इसलिए आकार निर्दिष्ट करें और इसे ठीक काम करना चाहिए। जी ++ निम्न कोड के साथ कोई समस्या नहीं है:

struct TestStruct { // note typedef is not needed */ 
    int length; 
    int values[3]; // specified the size 
}; 

TestStruct t = {3, {0, 1, 2}}; 

int main() { 
    // main implicitly returns 0 if none specified 
} 

संपादित करें: अपनी टिप्पणी को संबोधित करने के लिए, आप इस तरह टेम्पलेट का उपयोग कर सकते हैं:

template <int N> 
struct TestStruct { 
    int length; 
    int values[N]; 
}; 

TestStruct<3> t3 = {3, {0, 1, 2}}; 
TestStruct<2> t2 = {2, {0, 1}}; 

int main() {} 

केवल समस्या का कोई आसान तरीका है कि वहाँ है दोनों कंटेनर में टी 2 और टी 3 डालें (जैसे सूची/वेक्टर/स्टैक/कतार/आदि क्योंकि उनके पास अलग-अलग आकार हैं। अगर आप इसे चाहते हैं, तो आपको std::vector का उपयोग करना चाहिए। इसके अलावा, यदि आप ऐसा कर रहे हैं, तो यह आवश्यक नहीं है आकार को स्टोर करने के लिए (यह प्रकार से जुड़ा हुआ है)। तो आप इसके बजाय ऐसा कर सकते हैं:

template <int N> 
struct TestStruct { 
    static const int length = N; 
    int values[N]; 
}; 

TestStruct<3> t3 = {{0, 1, 2}}; 
TestStruct<2> t2 = {{0, 1}}; 

int main() {} 

लेकिन एक बार फिर, आप आसानी से "संग्रह" में टी 2 और टी 3 नहीं डाल सकते हैं।

संपादित करें: सभी सब में, यह आप की तरह लगता है (जब तक आप बस कुछ संख्या और आकार की तुलना में अधिक डाटा स्टोर) सब पर एक struct की जरूरत नहीं है, और सिर्फ एक सादे पुराने वेक्टर उपयोग नहीं कर सकते ।

typedef std::vector<int> TestStruct; 


int t2_init[] = { 0, 1, 2 }; 
TestStruct t3(t3_init, t3_init + 3); 

int t2_init[] = { 0, 1 }; 
TestStruct t2(t2_init, t2_init + 2); 

int main() {} 

जो आपको एक साथ संग्रह में टी 2 और टी 3 दोनों रखने की अनुमति देगा। दुर्भाग्य से std::vector (अभी तक) सरणी शैली प्रारंभकर्ता वाक्यविन्यास नहीं है, इसलिए मैंने शॉर्टकट का उपयोग किया है। लेकिन एक अच्छा फैशन में वैक्टरों को पॉप्युलेट करने के लिए एक समारोह लिखना काफी आसान है।

संपादित करें: ठीक है, इसलिए आपको संग्रह की आवश्यकता नहीं है, लेकिन आपको इसे किसी फ़ंक्शन में पास करने की आवश्यकता है, आप टाइप सुरक्षा को संरक्षित रखने के लिए टेम्पलेट का उपयोग कर सकते हैं!

template <int N> 
struct TestStruct { 
    static const int length = N; 
    int values[N]; 
}; 

TestStruct<3> t3 = {{0, 1, 2}}; 
TestStruct<2> t2 = {{0, 1}}; 

template <int N> 
void func(const TestStruct<N> &ts) { /* you could make it non-const if you need it to modify the ts */ 
    for(int i = 0; i < N; ++i) { /* we could also use ts.length instead of N here */ 
     std::cout << ts.values[i] << std::endl; 
    } 
} 

// this will work too... 
template <class T> 
void func2(const T &ts) { 
    for(int i = 0; i < ts.length; ++i) { 
     std::cout << ts.values[i] << std::endl; 
    } 
} 

int main() { 
    func(t2); 
    func(t3); 
    func2(t2); 
} 
+0

क्या आप टाइपिफ़ में सरणी आकार निर्दिष्ट कर सकते हैं? किसी भी मामले में, मैं इस संरचना के कई उदाहरण घोषित कर रहा हूं, प्रत्येक एक अलग लंबाई सरणी के साथ। –

+0

शानदार! धन्यवाद - यह मेरी समस्या हल करता है! टेम्पलेट्स के बारे में चेतावनी के लिए धन्यवाद एक ही प्रकार नहीं है - मुझे उनमें से एक कंटेनर की आवश्यकता नहीं है, लेकिन मुझे उन्हें एक सामान्य कार्य में पास करने की आवश्यकता है। शून्य पॉइंटर्स और टाइपकास्टिंग को चाल चलनी चाहिए ... –

+0

एक नोट है कि मैं केवल वैक्टर का उपयोग क्यों नहीं कर सकता - मैं वास्तव में सीपीयू रजिस्टरों के बारे में कुछ जानकारी संग्रहीत कर रहा हूं जिन्हें विभिन्न आर्किटेक्चर के लिए पढ़ने की आवश्यकता है। रजिस्टर पतों की सरणी के अलावा मुझे पढ़ने की जरूरत है, रजिस्टरों की प्रत्येक श्रृंखला तक पहुंचने के तरीके के बारे में निर्दिष्ट करने के लिए लगभग 8 अन्य 32-बिट पूर्णांक आवश्यक हैं। जब मैं अपना (बल्कि मूर्खतापूर्ण) परीक्षण केस बना रहा था, तो इन अन्य चीजों को "अनुकूलित" किया गया। –

0

VLA केवल सी 99 में समर्थित है। सी ++ इसका समर्थन नहीं करता है। http://gcc.gnu.org/c99status.html से, जीसीसी अब वीएलए का समर्थन करता है।

1
struct TestStruct { 
    int length; 
    const int *values; 
}; 

static const uint8_t TEST_STRUCT_VAL_1[] = {0, 1, 2}; 
const TestStruct t1 = {3, TEST_STRUCT_VAL_1}; 

static const uint8_t TEST_STRUCT_VAL_2[] = {0, 1, 2, 3}; 
const TestStruct t2 = {4, TEST_STRUCT_VAL_2};` 

मेरे मामले में, जीसीसी के साथ STM32 प्रोग्रामिंग/जी ++, मान सरणी में तो यह स्थिर स्थिरांक है, और फ्लैश में संग्रहीत किया जाएगा, केवल कच्चे डेटा भंडारण है। मैं एलसीडी डिस्प्ले के लिए फ़ॉन्ट पैटर्न स्टोर करने के लिए इस तरह का उपयोग करता हूं।

टेम्पलेट का उपयोग कर बचत टाइपिंग है, लेकिन आकार की बचत नहीं है।

2

जीसीसी/बजना समर्थन निम्न एक्सटेंशन

 

    typedef struct TestStruct 
    { 
     int length; 
     int* values; 
    }; 

    TestStruct t = {3, (int[]){0, 1, 2}}; 
    TestStruct t2 = {4, (int[]){0, 1, 2, 3}}; 

+0

यह केवल स्थिर/वैश्विक स्तर पर काम करेगा। यदि आप इसे किसी विधि के भीतर करते हैं, तो कंपाइलर इन्ट्स की अस्थायी सरणी उत्पन्न करेगा, इसे स्ट्रक्चर पर असाइन करेगा और फिर सरणी को तुरंत खराब कर देगा, जिससे खराब पॉइंटर के साथ स्ट्रक्चर को छोड़ दिया जा सके; यदि आप ऐसा करने का प्रयास करते हैं तो जीसीसी चेतावनी देता है। – adelphus