2016-09-13 7 views
6

मैं साल प्राप्त कर रहा में दिनों की संख्या का निर्धारण, महीने आदानों के रूप में और दिन और मैं एक कुशल तरीके से आदानों मान्य करने के लिए कोशिश कर रहा हूँ। वर्ष रेंज [0-99] (0,4,8 .. लीप वर्ष माना जाता है), महीने रेंज [1-12] और दिन रेंज [1-31]।एक महीने

दिन मान्य के सीधे आगे रास्ता निम्नलिखित होगा:

if((Day<1u) || (Day>31u)){ 
    /*error*/ 
} 
else if ((Month==4u) || (Month==6u) || (Month==9u) || (Month==11u) && (Day>30u)){ 
    /*error*/ 
} 
else if ((Month==2u) && (Year % 4u == 0u) && (Day > 29u)){ 
    /*error*/ 
} 
else if ((Month==2u) && (Year % 4u != 0u) && (Day > 28u)){ 
    /*error*/ 
} 
else 
{ 
    /*valid*/ 
} 

लेकिन यह एक उच्च जटिलता है।

एक लुकअप तालिका एक बेहतर विकल्प की तरह लगता है। और अब सवाल:

इस मामले निम्नलिखित के अलावा अन्य के लिए तालिका बनाने के लिए एक अधिक कुशल तरीका है?

const int testTable[4][12] = { 
    {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 
    {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 
    {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 
    {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} 
}; 

if(testTable[ Year % 4 ][ Month - 1 ] >= Day){ 
    /*valid*/ 
} 
else{ 
    /*error*/ 
} 

क्या कोई और नियम है जिसे मैं नहीं देख रहा हूं?

+0

से बच सकते हैं क्या यह एम्बेडेड सिस्टम के साथ क्या करना है? मैं टैग हटा दूंगा। – Lundin

+2

आप पहले से ही Y2K के सबक भूल गए हैं? या जब आप ऐसा हुआ तो आप चारों ओर नहीं थे? साल के लिए दो अंकों का उपयोग लंबे समय तक दुखी होने के लिए एक नुस्खा है। उदाहरण के लिए, 2100 एक छलांग वर्ष नहीं है, और न तो 1 9 00 था, हालांकि 2000 था। करुणा के लिए, 4 अंकों के वर्षों का उपयोग करें! –

+0

यह बदतर बनाने के लिए, आप 400 –

उत्तर

6

आप लीप वर्ष के लिए एक आयाम और गैर छलांग साल के लिए एक दूसरे की जरूरत है:

int isleap(int year) 
{ 
    return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); 
} 

int mthdays(int month, int year) 
{ 
    static const int days[2][13] = { 
     {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 
     {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} 
    }; 
    int leap = isleap(year); 

    return days[leap][month]; 
} 

साल रेंज है [0-99] (0,4,8 .. लीप वर्ष माना जाता है)

फिर अपने isleap() समारोह होना चाहिए:

int isleap(int year) 
{ 
    return (year % 4 == 0); 
} 

महीने रेंज [1-12]

का उपयोग करना:

{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} 

बजाय

{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} 

आप [ Month - 1 ]

+0

सहमत, लेकिन 2 आयामों के साथ मैं एक अतिरिक्त समारोह कॉल या एक अतिरिक्त जांच की जरूरत है। –

+0

ध्यान दें कि आप इस्तेमाल कर सकते हैं (अहस्ताक्षरित) 'char' संख्या स्टोर करने के लिए, अंतरिक्ष की बचत।आप 'isleap()' को 'स्थिर इनलाइन' फ़ंक्शन में बना सकते हैं और संकलक लगभग निश्चित रूप से सरल रूप से इनलाइन कर देगा (जिसे 'रिटर्न ((वर्ष और 0x3) == 0) में संशोधित किया जा सकता है; वास्तविक विभाजन से बचने के लिए कंपाइलर, विशेष रूप से यदि आप 'वर्ष' के लिए 'हस्ताक्षरित' का उपयोग करते हैं, जो संकलक को बताता है कि उसे नकारात्मक मानों के बारे में चिंता करने की आवश्यकता नहीं है। –

+0

@ जोनाथन लेफ्लर, आप 'हस्ताक्षरित' प्रकार के बारे में सही हैं, लेकिन में वास्तविक दुनिया हम आम तौर पर 'हस्ताक्षर int' का उपयोग करते हैं, एक बार मुझे 'ग्लिब' का उपयोग करना पड़ता था (जहां [दिनांक और समय] के लिए पैराम्स (https://developer.gnome.org/glib/stable/glib-Date-and-Time- Functions.html) को 'guint16' के लिए टाइप किया गया है) और कोड को लगभग हमेशा एक कास्ट की आवश्यकता होती है। –

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