सी

2011-11-29 2 views
7

में अबाधित नाव सरणी typedef मैं इस तरह नाव सरणियों के लिए एक typedef बनाया,:सी

typedef float fooType[]; 

ताकि मैं घोषणा और इस तरह स्थिर नाव सरणियों आरंभ कर सकते हैं:

fooType myArray = {1.0, 2.0, 3.0} 

यही काम करता है ठीक। मैं myArray[2] कह सकता हूं बिना किसी समस्या के और आमतौर पर मेरे fooType का उपयोग करना चाहूंगा। मेरे कार्यक्रम के संदर्भ में यह बहुत स्पष्ट है कि fooType एक सरणी प्रकार है (यह वास्तव में एक विशाल लुकअप टेबल है) यही कारण है कि मैं बस typedef float fooType नहीं कर रहा हूं।

फिर मैं bar पर इंगित करने के लिए एक चर का उपयोग और उपयोग कैसे करूं और bar के तत्वों तक पहुंच सकता हूं? मैं इस तरह एक साधारण चर की घोषणा नहीं कर सकते हैं:

fooType bar = myArray; 

invalid initializer साथ कि त्रुटियों के बाद से; मुझे यह काम करने की उम्मीद नहीं थी क्योंकि संकलक को पता नहीं था कि आवंटित करने के लिए कितनी मेमोरी है।

fooType *bar = myArray; 

यह एक चेतावनी देता है:: मैं संकेत के साथ कुछ बातें करने की कोशिश की जब मैं bar[1] साथ तत्वों का उपयोग initialization from incompatible pointer type और त्रुटियों .. यह ठीक वाणी, के रूप में मैं इसे बाद प्रकार अब मैच के लिए उम्मीद थी:

fooType *bar = &myArray; 

लेकिन invalid use of array with unspecified bounds के साथ कंपाइलर त्रुटियों के ऊपर जैसा कि मैं bar[1] कहता हूं।

यह काम करता है:

float *bar = myArray; 
float val = bar[3]; 

लेकिन मैं क्योंकि मैं अपने typedef की पठनीयता कम करने के लिए नहीं करना चाहती।

मुझे एक कट्टरपंथी ओओ दुनिया (जावा) में लंबे समय तक दफनाया गया है, इसलिए मुझे इस स्थिति में सी में बेवकूफ़ों के बारे में समझने की उम्मीद है। अगर कोई सीधा समाधान नहीं है तो मैं कटाई के अनुरूप टाइपिफ़ के उपयोग को बदलने के लिए तैयार हूं। मुझे लगता है कि वहां एक भावना है, और यह जटिल नहीं है।

धन्यवाद

+0

लब्बोलुआब यह है कि तुम क्या है ** नहीं ** सरणियों के लिए ... आप कर सकते हैं typedefs बनाना चाहते हैं, लेकिन फिर आप उन सभी "परेशानियों" सामना करते हैं। उदाहरण के लिए यह बात 'fooType myArray = {1.0, 2.0, 3.0}; fooType बार = myArray; 'का अर्थ है' मेरा आरा फ़्लोट [] = {1.0, 2.0, 3.0}; फ्लोट बार [] = myArray; 'क्या यह पठनीय है? जब आप एक समारोह प्रोटोटाइप जो 'fooType' _output_ तर्क के रूप में लेता है परिभाषित :) एक और" पहेली "है। ('Memset', आदि के समान) – debleek63

+0

अब यह अधिक @ debleek63 स्पष्ट है। धन्यवाद। –

उत्तर

5

आप जिस समस्या का सामना कर रहे हैं वह यह तथ्य है कि सरणी सी में पॉइंटर्स नहीं हैं, बल्कि असाइनमेंट ऑपरेटर के दाईं ओर उपयोग किए जाने वाले पहले तत्व को पॉइंटर्स को क्षय नहीं करते हैं।इस प्रकार, आप की तरह

fooType myArray = {1.0, 2.0, 3.0} 

myArray के प्रकार float[3] है, और & myArray (*float)[3], या "3 तैरता की एक सरणी के लिए सूचक" है एक सरणी यह ​​घोषणा करते हैं। इस प्रकार आप बस यह नहीं कह सकते

fooType *bar = myArray; 

प्रकार fooType* एक नाव के लिए सूचक नहीं है ... इस प्रकार यह एक असंगत सूचक प्रकार है। कर

fooType* bar = &myArray; 

काम करता है, लेकिन जब से bar ही एक सूचक है समस्या आप का सामना कर रहे हैं, कि bar[1] सरणी myArray का एक भाग नहीं है। myArray में किसी तत्व तक पहुंचने के लिए आपको bar(*bar)[1] की तरह अव्यवस्था करना होगा। उदाहरण के लिए:

typedef float fooType[]; 
fooType myArray = {1.0, 2.0, 3.0} 
fooType* bar = &myArray; 
(*bar)[1] = 5.0; 

अंत में, यह ध्यान रखें कि सी के साथ, आप एक और सरणी के लिए एक सरणी आवंटित नहीं कर सकते हैं ... तो आप की तरह कुछ करना can'd:

fooType bar = myArray; 

यह करने के लिए वापस चला जाता है सरणी के पूरे अंक और उनके तत्व को पहले तत्व के लिए पॉइंटर्स में, और तथ्य यह है कि सरणी का प्रकार सरणी में पहले तत्व के प्रकार के समान नहीं है।

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

+0

धन्यवाद जेसन। यह अब थोड़ा स्पष्ट है। मैं तब टाइपिफ़ का उपयोग नहीं कर सकता, ऐसा लगता है, क्योंकि इसका प्रकार है ... 'float []'? क्या मुझे इसके बजाय 'फ्लोट * बार = myArray' का उपयोग करना चाहिए? पठनीय नहीं है लेकिन यह काम करता है। –

+0

मुझे संकलन समय पर सरणी का आकार पता है, इसलिए आपका दूसरा विकल्प काम करेगा, लेकिन आपके दोनों सुझावों ने बहुत मदद की है। धन्यवाद। –

+0

बीटीडब्ल्यू, मैंने अपना जवाब थोड़ा सा बदल दिया ... ऐसा लगता है कि आपके समाधानों में से एक को अवरुद्ध करने वाली एक वाक्यविन्यास त्रुटि थी। – Jason

1

आपके पास जावा के साथ मिश्रित सी है।

typedef float *fooType; 

बाद में करने के लिए अपने typedef बदलने की कोशिश, फिर भी आप की तरह

fooType myArray = {1.0, 2.0, 3.0}; 

प्रकार fooType के एक चर प्रारंभ करने में सक्षम नहीं होगा क्योंकि fooType अब सूचक है।

+0

एक 'typedef' के पीछे एक सूचक प्रकार छिपाई जा रही है आम तौर पर खराब व्यवहार का ... –

+0

माना जाता है @OliCharlesworth उफ़। धन्यवाद। मैं सिर्फ काम करने के लिए ओ पी के कोड चाहता था। – Beginner

+0

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

0

विजुअल स्टूडियो 2013 का उपयोग करते हुए मैंने पाया कि आप इस तरह के इस उदाहरण में निर्माणों इस्तेमाल कर सकते हैं। यह भी दृश्य स्टूडियो के साथ काम करने लगता है 2015

सूचना है कि malloc() के उपयोग fooType की एक सरणी बनाने के लिए प्रकार pfooType बजाय fooType या *pfooType के प्रकार को संकलित करने का एक dereferenced सूचक की आवश्यकता है। मैंने float से double और sizeof(*p2) से 4 से 8 बाइट्स में बदलकर उम्मीद की।

#include <malloc.h> 

typedef float fooType[], *pfooType; 

int xxmain2(void) 
{ 
    fooType myArray = { 1.0, 2.0, 3.0 }; // define the array with its elements 
    pfooType p = myArray; // get a pointer to the array. 
    int i; 
    int nElements = sizeof(myArray)/sizeof(*p); // determine number of elements in the array. 

    pfooType p2 = malloc(sizeof(*p2) * 5); // malloc() an array of 5 elements. 

    for (i = 0; i < 5; i++) p2[i] = (float)i * 10.0; // initialize my malloced array. 
    myArray[0] = *p;  // dereference pointer 
    myArray[1] = p[1];  // use array subscripting with pointer 

    for (i = 0, p = myArray; i < nElements; i++) *p++ = 0; // increment the pointer to traverse the array. 

    free(p2); 
    return 0; 
} 

मैंने यह भी पाया है कि मैं एक सरणी के एक निर्धारित आकार fooType myRay2[10]; (का संकलन त्रुटि "त्रुटि C2087: 'myRay2': लापता सबस्क्रिप्ट") की तरह कुछ के साथ नहीं बना सका या कुछ इसी तरह। और fooType myRay2; "त्रुटि C2133: 'myRay2': अज्ञात आकार" की संकलन त्रुटि देता है।

तो एकमात्र तरीका सरणी के आकार के प्रारंभिकरण का उपयोग करना या malloc() का उपयोग करने के लिए किसी विशेष आकार की सरणी बनाने के लिए उपयोग करना प्रतीत होता है जिसके बाद free() की आवश्यकता होती है।