2013-07-16 15 views
5

मैं अपेक्षाकृत सी प्रोग्रामिंग भाषा के लिए नया हूँ, और मैं एक समारोह है कि पैरामीटर के रूप में विभिन्न प्रकार के डेटा स्वीकार कर सकते हैं बनाने के लिए कैसे यह पता लगाने की कोशिश कर रहा हूँ स्वीकार करता है बनाएँ। फ़ंक्शन को किसी वर्ण या पूर्णांक सरणी में तत्वों की संख्या को गिनना और वापस करना माना जाता है। मेरे पास पहले से ही दो अलग-अलग फ़ंक्शन हैं जो ऐसा करेंगे, लेकिन मैं वास्तव में दोनों कार्यों के लिए एक फ़ंक्शन का उपयोग करने में सक्षम होना चाहता हूं। सी में ऐसा करने का कोई तरीका है?एक सी समारोह है कि विभिन्न डेटा प्रकार के मापदंडों

अग्रिम धन्यवाद!

उत्तर

5

सी में कोई मानक फ़ंक्शन ओवरलोडिंग नहीं है (न ही वहां टेम्पलेट्स हैं), लेकिन आप शायद "printf-like" फ़ंक्शंस (या variadic functions) देख सकते हैं और शायद वे आपको जो भी चाहिए वह कर सकते हैं। यदि वे कुछ भी लचीली पैरामीटर सूची के लिए अनुमति देते हैं।

इस तरह के एक समारोह है कि एक चर आकार पूर्णांक सरणी लेता है का एक उदाहरण here नहीं है।

शायद आप void iterate(const char* format, ...); के रूप में एक समारोह के हस्ताक्षर इस तरह हो सकता है कि आप निम्न तरीकों से उपयोग करें:

iterate("char", some_char_array); // for char arrays/strings 

या

iterate("int", some_int_array); // for integer arrays 

अनिकेत एक अच्छा बिंदु हालांकि बनाता है, आप तत्वों की गणना कैसे करूं एक पूर्णांक सरणी में? यदि आप एक तर्क के रूप में एक int सरणी पास करते हैं, तो आपको आकार को भी पारित करने की आवश्यकता होगी जो सरणी में तत्वों की गणना करने के उद्देश्य को हरा देता है (जैसा कि आप पहले ही जानते हैं कि आकार यानी)।

मैं तुम्हें आकार पता नहीं है मान लेते हैं, लेकिन आप सरणी (जैसे -1 के रूप में) में एक टर्मिनेटर मूल्य की है।

मैं कुछ जल्दी काट दिया थोड़े जो आपके मन में ऊपर धारणा के साथ की जरूरत है कि है।

#include <stdarg.h> 
#include <stdio.h> 
#include <string.h> 

int iterate(const char* format, ...) 
{ 
    va_list ap; 
    va_start(ap, format); 

    if (strcmp(format, "char") == 0) 
    { 
     char* array = va_arg(ap, char*); 

     return strlen(array); 
    } 
    else if (strcmp(format, "int") == 0) 
    { 
     int j = -1; 
     int* int_array = va_arg(ap, int*); 
     while (int_array[++j] != -1) 
        ;  
     return j; 
    } 
    return 0; 
} 

int main() 
{ 
    printf("%d\n", iterate("char", "abcdef")); 
    int arr[] = {5, 4, 3, 2, 1, 0, -1}; 
    printf("%d\n", iterate("int", arr)); 

    return 0; 
} 

यह प्रिंट:

$ ./a.out 
6 
6 
+0

'int size' क्या है? –

+0

सरणी का आकार? मैं इसे स्पष्ट कर दूंगा क्योंकि यह स्पष्ट नहीं है। – Nobilis

+0

अच्छी तरह से अगर वह हाथ से पहले सरणी के आकार को जानता है, तो वह इस तरह के सुपर फ़ंक्शन का उपयोग क्यों करेगा ताकि स्वचालित रूप से प्रकार का अनुमान लगाया जा सके और सरणी की लंबाई की गणना करने के लिए उपयुक्त फ़ंक्शन को कॉल किया जा सके? :-) –

1

आप अपने प्रकार्य तर्क एक void * प्रकार में ले बनाना चाहिए। इस तरह, आप विभिन्न प्रकार के डेटा में गुजर सकते हैं, और इसे अपनी इच्छानुसार टाइप-कास्ट कर सकते हैं। हालांकि, आपको यह देखने की ज़रूरत है क्योंकि void* अंक के प्रकार को सही तरीके से अनुमान लगाने का कोई गारंटी नहीं है।

2

या तो मामले में, आप टाइप inferencing प्रणाली के कुछ प्रकार की जरूरत है सी संकलक जो कॉल करने के लिए कार्य करते हैं बताने के लिए होगा। जिसका अर्थ है, आपको पता होना चाहिए कि पहले से ही उस सरणी के प्रकार को आप अपने "सुपर फ़ंक्शन" के पैरामीटर के रूप में भेज सकते हैं।

नहीं "ऑटो-प्रकार-inferencing" सी आप रनटाइम पर डेटा के प्रकार पर चिंतन करने दे सकते हैं कि में नहीं है। बेहतर अभी तक, आपको ऐसा होने के लिए अपना खुद का रनटाइम वातावरण लिखना पड़ सकता है।

एक थोड़ा तुच्छ hackish यह करने के लिए जिस तरह से:

#include <stdio.h> 

size_t GetLengthOfArray(size_t sizeOfOneElementInArray, size_t sizeOfTheArrayInBytes) 
{ 
    return sizeOfTheArrayInBytes/sizeOfOneElementInArray; 
} 
int main(int argc, char *argv[]) 
{ 
    char cArr[10] = {'A','B','C','D','E','F','G','H','I','J'}; 
    int iArr[5] = {10,20,30,40,50}; 
    printf("%d is the length of cArr\n%d is the length of iArr",GetLengthOfArray(sizeof(cArr[0]),sizeof(cArr)), 
                   GetLengthOfArray(sizeof(iArr[0]),sizeof(iArr))); 
    return 0; 
} 
+0

सी 11 में '_Generic' है। – jxh

2

तो चलिए अपने दो कार्यों मान लें sizeof_char_array और sizeof_int_array कहा जाता है।

#define sizeof_array(X) \ 
    _Generic (*(X), \ 
       char: sizeof_char_array, \ 
       default: sizeof_int_array) (X) 

(मैं भी परीक्षण करने के लिए एक सी 11 कार्यान्वयन की जरूरत नहीं है:

सी 11 में, वहाँ एक नई सुविधा "सामान्य चयन" आप एक अपेक्षाकृत सरल मैक्रो के साथ तुम क्या चाहते करने देंगे कहा जाता है इसके खिलाफ, इतनी चेतावनी emptor!)

सी 11 से पहले, यह कभी-कभी नियमित रूप से नामित कार्यों का उपयोग करके एक मैक्रो के साथ पूरा किया गया था। आप एक मैक्रो है कि एक समारोह या अन्य किसी मैक्रो तर्क संकेत के आधार पर फोन करेगा परिभाषित कर सकते हैं:

#define sizeof_array(xtype, x) sizeof_ ## xtype ##_array(x) 

int a[] = { 1, 2, 3, 4, -1 }; 
char b[] = "abc"; 

sizeof_array(int, a); /* macro expands to sizeof_int_array(a) */ 
sizeof_array(char, b); /* macro expands to sizeof_char_array(b) */ 

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

#define ARRAY_SZ(x) (sizeof(x)/((void *)x == &x ? sizeof(x[0]) : 0)) 

एक सरणी के मामले में, निम्नलिखित अभिव्यक्ति सत्य है:

(void *)arr == &arr 

क्योंकि एक सरणी का पता अपना पहला तत्व के पते के रूप में स्मृति में एक ही स्थान है।

तो, मैक्रो गणना करता है: sizeof(arr)/sizeof(arr[0])। चूंकि sizeof ऑपरेटर अपने तर्क के बाइट्स में आकार की रिपोर्ट करता है, इसलिए गणना की अभिव्यक्ति के परिणामस्वरूप सरणी में तत्वों की संख्या होती है। हालांकि, यदि आप लंबाई की गणना करने के लिए एक सेंटीनेल का उपयोग कर रहे हैं, तो ARRAY_SZ मैक्रो के परिणामस्वरूप सेंटीनेल के लिए सरणी को पार करने वाली लंबाई से कम से कम एक आकार का आकार होगा।

यदि तर्क एक सरणी नहीं है, तो अभिव्यक्ति का परिणाम 0 अपवाद से विभाजित होता है।

+0

कड़ाई से बोलते हुए :- पी, ओपी पॉइंटर के डेटा के प्रकार के आधार पर एक समारोह से दो अलग-अलग कार्यों को कॉल करना चाहता है। –

+0

तो मुझे लगता है, वह किसी प्रकार की टाइप-इनफ्रेंसिंग सिस्टम चाहता है। बस इस पर मेरा विचार। –

+0

@ एनीनेट: इससे मुझे ज्यादा समझ नहीं आती है, क्योंकि आप किसी फ़ंक्शन को पारित होने के बाद सरणी की लंबाई का अनुमान नहीं लगा सकते हैं। सरणी की लंबाई को फ़ंक्शन में पारित करने की आवश्यकता होती है (जब तक कि एक सेंटीनेल मान के माध्यम से अनुमान नहीं किया जाता है)। – jxh

2

उत्तर काफी सरल है। आपको इस कार्य के लिए एक फ़ंक्शन की आवश्यकता है। बस कोड के इस टुकड़े को आजमाएं

#define len(array) sizeof(array)/sizeof(array[0]) 

और यही वह है।

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