2017-06-24 22 views
9

यदि मैं एक सामान्य एल्गोरिदम लिख रहा हूं, तो क्या मुझे अज्ञात प्रकार की एक सरणी को एक सरणी के सूचक के रूप में उपनाम करने की अनुमति है, जहां प्रत्येक तत्व अपरिभाषित व्यवहार का आविष्कार किए बिना प्रदान किया गया आकार है?अक्षर के सरणी के लिए सूचक के माध्यम से सामान्य रूप से सरणी वस्तुओं तक पहुंच?

उदाहरण के लिए, क्या निम्नलिखित कोड में यूबी है?

typedef void (*action_t)(const void *item); 
void do(void *array, size_t eltCount, size_t eltSize, action_t action) 
{ 

    // Convenient typedef. 
    typedef char element[eltSize]; 
    element *elts = array; 
    element *end = elts + eltCount; 

    for (; elts != end; elts++) { 
     action(elts); 
    } 
} 

मैं जानता हूँ कि मैं यह कर सकता:

char *elts = array; 
char *end = elts + eltCount * eltSize; 

for (; elts != end; elts += eltSize) { 
    action(elts); 
} 

लेकिन चूंकि संकलक मेरे लिए सूचक अंकगणित करता कोड के पहले थोड़ा मेरे लिए अधिक मुहावरेदार लगता है। उपरोक्त फ़ंक्शन जीसीसी और क्लैंग दोनों का उपयोग करके चेतावनियों के बिना संकलित करता है (प्रासंगिक संकलन झंडे -std=c99 -O3 -fstrict-aliasing -pedantic-errors -Wextra -Wall हैं)। मैं सख्त अलियासिंग के बारे में भी सोच रहा हूं, लेकिन जहां तक ​​मैं कह सकता हूं, ऐसा लगता है कि मैं इसे तोड़ नहीं रहा हूं क्योंकि ऑब्जेक्ट्स को char* के माध्यम से अप्रत्यक्ष रूप से उपयोग करने की अनुमति है।

+0

आपका उत्तरार्द्ध उदाहरण कम से कम एक पॉइंटर को रद्द करने की उम्मीद वाले एक समारोह में एक एकल को पास करेगा। एक लेखन त्रुटि? –

+0

@ IljaEverilä इसे फिक्स्ड। धन्यवाद –

+0

यदि आप परेशानी में हैं तो 'qsort()' और 'bsearch()' भी हैं .., –

उत्तर

1

सी में, एक टाइपिफ़ एक नया प्रकार पेश नहीं करता है। यह सिर्फ एक निर्माण का नाम है। नाम और इसकी परिभाषा विस्थापन योग्य है। (struct के लिए यह भी सच नहीं है, जहां इसके नाम के अलावा संरचना की परिभाषा को व्यक्त करने का कोई तरीका नहीं है।)

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

संबंधित मुद्दे