जवाबों:
C में कहां
MIN
और क्याMAX
परिभाषित किया गया है, यदि बिलकुल नहीं है?
वे नहीं कर रहे हैं
इन्हें लागू करने का सबसे अच्छा तरीका क्या है, जैसा कि सामान्य रूप से संभव है और संभव के रूप में सुरक्षित है (मुख्यधारा के संकलक के लिए संकलक एक्सटेंशन / निर्मित)।
कार्यों के रूप में। #define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
यदि आप अपने कोड को तैनात करने की योजना बनाते हैं , तो मैं विशेष रूप से मैक्रोज़ का उपयोग नहीं करूंगा । या तो अपने स्वयं के, मानक की तरह कुछ उपयोग लिखने fmax
या fmin
, या का उपयोग कर मैक्रो ठीक जीसीसी के typeof एक में (आप typesafety भी बोनस प्राप्त) जीसीसी बयान अभिव्यक्ति :
#define max(a,b) \
({ __typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
_a > _b ? _a : _b; })
हर कोई कहता है "ओह मैं दोहरे मूल्यांकन के बारे में जानता हूं, यह कोई समस्या नहीं है" और सड़क से कुछ महीने नीचे, आप अंत में घंटों के लिए सबसे कठिन समस्याओं को डिबग करेंगे।
के __typeof__
बजाय के उपयोग पर ध्यान दें typeof
:
यदि आप एक हेडर फ़ाइल लिख रहे हैं जो आईएसओ सी कार्यक्रमों में शामिल होने पर काम करना चाहिए, तो
__typeof__
इसके बजाय लिखेंtypeof
।
decltype
कीवर्ड के साथ गड़बड़ करने की कोशिश करना है - लेकिन फिर भी, मैक्रो में विज़ुअल स्टूडियो यौगिक कथनों को नहीं कर सकता है (और decltype
वैसे भी C ++ है), यानी GCC का ({ ... })
सिंटैक्स तो मुझे पूरा यकीन है कि यह वैसे भी संभव नहीं है। मैं इस मुद्दे के बारे में किसी भी अन्य संकलक पर नहीं देखा है, खेद लूथर: एस
MAX(someUpperBound, someRandomFunction())
कुछ ऊपरी सीमा तक यादृच्छिक मान को सीमित करने के लिए किया था । यह एक भयानक विचार था, लेकिन यह भी काम नहीं करता था, क्योंकि MAX
वह दोहरे मूल्यांकन की समस्या का उपयोग कर रहा था, इसलिए वह शुरू में मूल्यांकन किए गए की तुलना में एक अलग यादृच्छिक संख्या के साथ समाप्त हो गया।
MIN(x++, y++)
प्रीप्रोसेसर को कॉल करते हैं , तो निम्न कोड उत्पन्न होगा (((x++) < (y++)) ? (x++) : (y++))
। तो, x
और y
दो बार वेतन वृद्धि की जाएगी।
यह GNU libc (लिनक्स) और sys / param.h के FreeBSD संस्करणों में भी प्रदान किया गया है, और इसमें ड्रीमलैक्स द्वारा दी गई परिभाषा है।
डेबियन पर:
$ uname -sr
Linux 2.6.11
$ cat /etc/debian_version
5.0.2
$ egrep 'MIN\(|MAX\(' /usr/include/sys/param.h
#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))
$ head -n 2 /usr/include/sys/param.h | grep GNU
This file is part of the GNU C Library.
FreeBSD पर:
$ uname -sr
FreeBSD 5.5-STABLE
$ egrep 'MIN\(|MAX\(' /usr/include/sys/param.h
#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))
स्रोत रिपोजिटरी यहाँ हैं:
openSUSE/Linux 3.1.0-1.2-desktop
/ के लिए gcc version 4.6.2 (SUSE Linux)
भी काम करता है। :) बुरा यह पोर्टेबल नहीं है।
वहाँ एक है std::min
और std::max
C ++, लेकिन AFAIK, वहाँ सी मानक पुस्तकालय में कोई समकक्ष है। आप उन्हें अपने आप को मैक्रोज़ जैसे परिभाषित कर सकते हैं
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
लेकिन यह समस्याओं का कारण बनता है अगर आप कुछ लिखते हैं MAX(++a, ++b)
।
#define MIN(A, B) ((A < B) ? A : B)
एक लचीला तरीका नहीं है, क्यों ???
#define MULT(x, y) x * y
। फिर MULT(a + b, a + b)
फैलता है a + b * a + b
, जो a + (b * a) + b
कि पूर्वगामी होने के कारण पार्स करता है। शायद यही प्रोग्रामर का इरादा था।
गैर-मानक संकलक एक्सटेंशन से बचें और इसे शुद्ध मानक C (ISO 9899: 2011) में पूरी तरह से सुरक्षित मैक्रो के रूप में लागू करें।
समाधान
#define GENERIC_MAX(x, y) ((x) > (y) ? (x) : (y))
#define ENSURE_int(i) _Generic((i), int: (i))
#define ENSURE_float(f) _Generic((f), float: (f))
#define MAX(type, x, y) \
(type)GENERIC_MAX(ENSURE_##type(x), ENSURE_##type(y))
प्रयोग
MAX(int, 2, 3)
व्याख्या
मैक्रो मैक्स type
पैरामीटर के आधार पर एक और मैक्रो बनाता है । यह नियंत्रण मैक्रो, यदि दिए गए प्रकार के लिए लागू किया जाता है, तो यह जांचने के लिए उपयोग किया जाता है कि दोनों पैरामीटर सही प्रकार के हैं। यदि type
समर्थित नहीं है, तो संकलक त्रुटि होगी।
यदि या तो x या y सही प्रकार का नहीं है, तो ENSURE_
मैक्रोज़ में संकलक त्रुटि होगी । यदि अधिक प्रकार का समर्थन किया जाता है तो अधिक मैक्रो को जोड़ा जा सकता है। मैंने मान लिया है कि केवल अंकगणित प्रकार (पूर्णांक, फ़्लोट्स, पॉइंटर्स आदि) का उपयोग किया जाएगा और न कि संरचित या बन्दी आदि।
यदि सभी प्रकार सही हैं, तो GENERIC_MAX मैक्रो कहा जाएगा। प्रत्येक मैक्रो पैरामीटर के आसपास अतिरिक्त कोष्ठक की आवश्यकता होती है, सी मैक्रोज़ लिखते समय सामान्य मानक एहतियात के रूप में।
फिर सी में निहित प्रकार के प्रचार के साथ सामान्य समस्याएं हैं। ?:
ऑपरेटर एक दूसरे के खिलाफ दूसरे और तीसरे ऑपरेटर को संतुलित करता है। उदाहरण के लिए, का परिणाम GENERIC_MAX(my_char1, my_char2)
होगा int
। मैक्रो को इस तरह के संभावित खतरनाक प्रकार के प्रचार करने से रोकने के लिए, अंतिम प्रकार के लिए इच्छित प्रकार का उपयोग किया गया था।
दलील
हम चाहते हैं कि दोनों पैरामीटर मैक्रो के लिए एक ही प्रकार के हों। यदि उनमें से एक अलग प्रकार का है, तो मैक्रो अब सुरक्षित प्रकार नहीं है, क्योंकि एक ऑपरेटर जैसे ?:
अंतर्निहित प्रकार के पदोन्नति देगा। और क्योंकि यह करता है, हमें हमेशा अंतिम परिणाम वापस करने की आवश्यकता होती है जैसा कि ऊपर बताया गया है।
केवल एक पैरामीटर के साथ एक मैक्रो को बहुत सरल तरीके से लिखा जा सकता था। लेकिन 2 या अधिक मापदंडों के साथ, एक अतिरिक्त प्रकार के पैरामीटर को शामिल करने की आवश्यकता है। क्योंकि ऐसा कुछ दुर्भाग्य से असंभव है:
// this won't work
#define MAX(x, y) \
_Generic((x), \
int: GENERIC_MAX(x, ENSURE_int(y)) \
float: GENERIC_MAX(x, ENSURE_float(y)) \
)
समस्या यह है कि यदि उपरोक्त मैक्रो को MAX(1, 2)
दो के साथ कहा जाता है int
, तो यह अभी भी _Generic
एसोसिएशन सूची के सभी संभावित परिदृश्यों को मैक्रो-विस्तारित करने का प्रयास करेगा । तो ENSURE_float
मैक्रो का विस्तार भी हो जाएगा, भले ही यह प्रासंगिक न हो int
। और चूंकि मैक्रो में जानबूझकर केवल float
प्रकार होता है , कोड संकलन नहीं करेगा।
इसे हल करने के लिए, मैंने ## ऑपरेटर के साथ पूर्व-प्रोसेसर चरण के दौरान मैक्रो नाम बनाया, ताकि कोई मैक्रो गलती से विस्तारित न हो जाए।
उदाहरण
#include <stdio.h>
#define GENERIC_MAX(x, y) ((x) > (y) ? (x) : (y))
#define ENSURE_int(i) _Generic((i), int: (i))
#define ENSURE_float(f) _Generic((f), float: (f))
#define MAX(type, x, y) \
(type)GENERIC_MAX(ENSURE_##type(x), ENSURE_##type(y))
int main (void)
{
int ia = 1, ib = 2;
float fa = 3.0f, fb = 4.0f;
double da = 5.0, db = 6.0;
printf("%d\n", MAX(int, ia, ib)); // ok
printf("%f\n", MAX(float, fa, fb)); // ok
//printf("%d\n", MAX(int, ia, fa)); compiler error, one of the types is wrong
//printf("%f\n", MAX(float, fa, ib)); compiler error, one of the types is wrong
//printf("%f\n", MAX(double, fa, fb)); compiler error, the specified type is wrong
//printf("%f\n", MAX(float, da, db)); compiler error, one of the types is wrong
//printf("%d\n", MAX(unsigned int, ia, ib)); // wont get away with this either
//printf("%d\n", MAX(int32_t, ia, ib)); // wont get away with this either
return 0;
}
GENERIC_MAX
मैक्रो का एक बुरा विचार है, आपको केवल यह GENERIC_MAX(var++, 7)
पता लगाने की कोशिश करनी है कि क्यों :-) आजकल (विशेष रूप से भारी अनुकूलन / इनलाइंग कंपाइलर्स के साथ), मैक्रोज़ को केवल सरल रूपों में ही बहुत अधिक बार पुनर्प्राप्त किया जाना चाहिए। फ़ंक्शन-जैसे वाले फ़ंक्शन के रूप में बेहतर होते हैं और मान-समूह वाले एन्यूमरेशन के रूप में बेहतर होते हैं।
मुझे नहीं लगता कि वे मानकीकृत मैक्रोज़ हैं। फ़्लोटिंग पॉइंट के लिए पहले से ही मानकीकृत फ़ंक्शन हैं, fmax
और fmin
(और fmaxf
फ़्लोट्स के लिए, और fmaxl
लंबे डबल्स के लिए)।
जब तक आप साइड-इफेक्ट्स / दोहरे मूल्यांकन के मुद्दों के बारे में जानते हैं, तब तक आप उन्हें मैक्रोज़ के रूप में लागू कर सकते हैं।
#define MAX(a,b) ((a) > (b) ? a : b)
#define MIN(a,b) ((a) < (b) ? a : b)
ज्यादातर मामलों में, आप इसे यह निर्धारित करने के लिए संकलक पर छोड़ सकते हैं कि आप क्या कर रहे हैं और इसे सर्वश्रेष्ठ के रूप में अनुकूलित कर सकते हैं। जब यह समस्याओं का कारण बनता है MAX(i++, j++)
, जैसे कि इस्तेमाल किया जाता है , तो मुझे संदेह है कि एक बार में बढ़े हुए मूल्यों की अधिकतम जांच करने की आवश्यकता है। पहले इन्क्रीमेंट, फिर चेक।
यह एक हाल ही में विकास के कारण, एक देर से जवाब है। चूंकि ओपी ने गैर-पोर्टेबल जीसीसी (और क्लैंग) एक्सटेंशन पर निर्भर होने वाले जवाब को स्वीकार कर लिया है typeof
- या __typeof__
'क्लीन' आईएसओ सी के लिए - वहाँ एक बेहतर समाधान उपलब्ध है gcc-4.9 ।
#define max(x,y) ( \
{ __auto_type __x = (x); __auto_type __y = (y); \
__x > __y ? __x : __y; })
इस विस्तार का स्पष्ट लाभ यह है कि प्रत्येक मैक्रो तर्क केवल एक बार __typeof__
समाधान के विपरीत विस्तारित होता है ।
__auto_type
C ++ 11 का सीमित रूप है auto
। यह C ++ कोड में उपयोग नहीं किया जा सकता है (या नहीं?), हालांकि auto
C ++ 11 का उपयोग करते समय बेहतर प्रकार की इंजेक्शन क्षमताओं का उपयोग नहीं करने का कोई अच्छा कारण नहीं है ।
उस ने कहा, मुझे लगता है कि मैक्रो को एक extern "C" { ... }
दायरे में शामिल करने पर इस सिंटैक्स का उपयोग करने में कोई समस्या नहीं है ; जैसे, C हेडर से। AFAIK, इस एक्सटेंशन ने अपने तरीके की जानकारी नहीं ली है
c-preprocessor
टैग है। जब तक gcc की __always_inline__
विशेषता जैसी किसी चीज का उपयोग नहीं किया जाता है, तब तक किसी फ़ंक्शन को उक्त कीवर्ड के साथ इनलाइन किए जाने की गारंटी नहीं है ।
मैंने यह संस्करण लिखा है जो MSVC, GCC, C, और C ++ के लिए काम करता है।
#if defined(__cplusplus) && !defined(__GNUC__)
# include <algorithm>
# define MIN std::min
# define MAX std::max
//# define TMIN(T, a, b) std::min<T>(a, b)
//# define TMAX(T, a, b) std::max<T>(a, b)
#else
# define _CHOOSE2(binoper, lexpr, lvar, rexpr, rvar) \
({ \
decltype(lexpr) lvar = (lexpr); \
decltype(rexpr) rvar = (rexpr); \
lvar binoper rvar ? lvar : rvar; \
})
# define _CHOOSE_VAR2(prefix, unique) prefix##unique
# define _CHOOSE_VAR(prefix, unique) _CHOOSE_VAR2(prefix, unique)
# define _CHOOSE(binoper, lexpr, rexpr) \
_CHOOSE2( \
binoper, \
lexpr, _CHOOSE_VAR(_left, __COUNTER__), \
rexpr, _CHOOSE_VAR(_right, __COUNTER__) \
)
# define MIN(a, b) _CHOOSE(<, a, b)
# define MAX(a, b) _CHOOSE(>, a, b)
#endif
यदि आपको एक महंगी शाखा से बचने के लिए न्यूनतम / अधिकतम की आवश्यकता है, तो आपको टर्नरी ऑपरेटर का उपयोग नहीं करना चाहिए, क्योंकि यह एक छलांग के लिए संकलित होगा। नीचे दिए गए लिंक में ब्रांचिंग के बिना मिनट / अधिकतम फ़ंक्शन को लागू करने के लिए एक उपयोगी विधि का वर्णन किया गया है।
http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax
@ दाविद टिटारेंको ने यहां पर इसे बंद कर दिया , लेकिन मुझे कम से कम इसे साफ करने के लिए थोड़ा साफ करने दें, और यहां से नकल और चिपकाने को आसान बनाने के लिए दोनों min()
को max()
एक साथ दिखाएं । :)
25 अप्रैल 2020 को अपडेट करें: मैंने यह दिखाने के लिए कि यह कैसे C ++ टेम्पलेट के साथ भी किया जाएगा, धारा 3 को जोड़ा है, C और C ++ दोनों को सीखने वालों के लिए एक मूल्यवान तुलना के रूप में, या एक से दूसरे में संक्रमण करना। मैंने पूरी कोशिश की है कि मैं पूरी तरह से तथ्यात्मक और सही साबित होऊं और इस जवाब को एक विवादास्पद संदर्भ बनाऊं जो मैं बार-बार वापस आ सकता हूं, और मुझे उम्मीद है कि आप इसे मेरे लिए उतना ही उपयोगी पाएंगे।
इस तकनीक का आमतौर पर उपयोग किया जाता है, अच्छी तरह से उन लोगों द्वारा सम्मानित किया जाता है जो इसे ठीक से उपयोग करना जानते हैं, चीजों को करने का "वास्तविक" तरीका है, और अगर ठीक से उपयोग किया जाता है, तो ठीक है, लेकिन छोटी गाड़ी (सोचें: दोहरे मूल्यांकन के दुष्प्रभाव ) यदि आप तुलना करने के लिए चर असाइनमेंट सहित कभी भी अभिव्यक्तियाँ :
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define MIN(a,b) ((a) < (b) ? (a) : (b))
यह तकनीक उपरोक्त "दोहरे-मूल्यांकन" दुष्प्रभावों और बग से बचा जाता है, और इसलिए इसे बेहतर, सुरक्षित और "अधिक आधुनिक" जीसीसी सी तरीका माना जाता है । यह अपेक्षा करें कि दोनों gcc और clang संकलक के साथ काम करें, क्योंकि clang है, डिज़ाइन द्वारा, gcc- संगत (इस उत्तर के निचले भाग में clang नोट देखें)।
लेकिन: " वैरिएबल शैडोइंग " इफेक्ट्स को अभी भी देखें, क्योंकि स्टेटमेंट एक्सप्रेशंस जाहिरा तौर पर इनबिल्ट हैं और इसलिए उनका अपना वैरिएबल स्कोप स्कोप नहीं है!
#define max(a,b) \
({ \
__typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
_a > _b ? _a : _b; \
})
#define min(a,b) \
({ \
__typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
_a < _b ? _a : _b; \
})
ध्यान दें कि gcc स्टेटमेंट एक्सप्रेशन में, कोड ब्लॉक में अंतिम एक्सप्रेशन है जो कि एक्सप्रेशन से "वापस" है, जैसे कि इसे किसी फंक्शन से लौटाया गया हो। जीसीसी के प्रलेखन यह इस तरह कहते हैं:
यौगिक कथन में अंतिम चीज एक अभिव्यक्ति होनी चाहिए जिसके बाद अर्धविराम होता है; इस उपसंचाई का मान पूरे निर्माण के मूल्य के रूप में कार्य करता है। (यदि आप ब्रेसिज़ के भीतर किसी अन्य प्रकार के कथन का उपयोग करते हैं, तो निर्माण में टाइप शून्य है, और इस प्रकार प्रभावी रूप से कोई मूल्य नहीं है)
C ++ नोट: यदि C ++ का उपयोग किया जाता है, तो इस प्रकार के निर्माण के लिए संभवतः टेम्पलेट्स की सिफारिश की जाती है, लेकिन मैं व्यक्तिगत रूप से टेम्पलेट्स को नापसंद करता हूं और संभवतः C ++ में उपरोक्त निर्माणों में से एक का उपयोग करेगा, जैसा कि मैं अक्सर उपयोग करता हूं और एम्बेडेड C ++ में C शैलियों को भी पसंद करता हूं।
इस खंड में 25 अप्रैल 2020 जोड़ा गया:
मैं पिछले कुछ महीनों से C ++ का एक टन कर रहा हूं, और मैक्रो पर टेम्पलेट पसंद करने का दबाव, जहां C ++ समुदाय में सक्षम है, काफी मजबूत है। नतीजतन, मैं टेम्प्लेट का उपयोग करने में बेहतर हो रहा हूं, और पूर्णता के लिए यहां C ++ टेम्प्लेट संस्करणों में रखना चाहता हूं और इसे अधिक विहित और पूरी तरह से उत्तर देना चाहता हूं।
यहाँ क्या मूल फ़ंक्शन टेम्पलेट संस्करण हैं max()
और min()
C ++ में दिख सकते हैं:
template <typename T>
T max(T a, T b)
{
return a > b ? a : b;
}
template <typename T>
T min(T a, T b)
{
return a < b ? a : b;
}
C ++ टेम्प्लेट के बारे में यहाँ अतिरिक्त रीडिंग करें: विकिपीडिया: टेम्प्लेट (C ++) ।
हालांकि, दोनों max()
और min()
पहले से ही सी ++ मानक पुस्तकालय का हिस्सा है, में हैं <algorithm>
हैडर ( #include <algorithm>
)। C ++ मानक पुस्तकालय में वे मेरे द्वारा ऊपर की तुलना में थोड़ा अलग तरीके से परिभाषित किए गए हैं। के लिए डिफ़ॉल्ट प्रोटोटाइप std::max<>()
और std::min<>()
, उदाहरण के लिए, सी ++ 14 में, बस ऊपर cplusplus.com लिंक में अपने प्रोटोटाइप को देखते हुए, इस प्रकार हैं:
template <class T>
constexpr const T& max(const T& a, const T& b);
template <class T>
constexpr const T& min(const T& a, const T& b);
ध्यान दें कि कीवर्ड typename
को किसी अन्य नाम है class
(ताकि उनके उपयोग समान है कि क्या आप कहते हैं कि <typename T>
या <class T>
), क्योंकि यह बाद में सी ++ टेम्पलेट्स के आविष्कार के बाद स्वीकार किया गया था, कि टेम्पलेट प्रकार एक नियमित प्रकार हो सकता है ( int
, float
आदि) केवल के बजाय एक वर्ग प्रकार।
यहां आप देख सकते हैं कि दोनों इनपुट प्रकार, साथ ही रिटर्न प्रकार, हैं const T&
, जिसका अर्थ है "टाइप करने के लिए निरंतर संदर्भ T
"। इसका मतलब है कि इनपुट पैरामीटर्स और रिटर्न वैल्यू को पास किए गए मान के बजाय संदर्भ द्वारा पास किया जाता है । यह पॉइंटर्स से गुजरने जैसा है, और बड़े प्रकारों के लिए अधिक कुशल है, जैसे कि क्लास ऑब्जेक्ट। constexpr
फ़ंक्शन का हिस्सा स्वयं फ़ंक्शन को संशोधित करता है और इंगित करता है कि फ़ंक्शन का संकलन-समय (कम से कम यदि इनपुट पैरामीटर प्रदान किया गया है ) पर मूल्यांकन करने में सक्षम होना चाहिएconstexpr
, लेकिन यदि संकलन-समय पर इसका मूल्यांकन नहीं किया जा सकता है, तो यह वापस डिफॉल्ट करता है रन-टाइम मूल्यांकन, किसी अन्य सामान्य कार्य की तरह।
constexpr
C ++ फ़ंक्शन का संकलन-समय पहलू इसे C-मैक्रो-की तरह बनाता है, जिसमें यदि किसी constexpr
फ़ंक्शन के लिए संकलन-समय का मूल्यांकन संभव है , तो यह संकलन-समय पर किया जाएगा, जैसे कि MIN()
या MAX()
मैक्रो प्रतिस्थापन संभव हो सकता है C या C ++ में भी संकलन-समय पर पूरी तरह से मूल्यांकन किया जाए। इस C ++ टेम्पलेट जानकारी के लिए अतिरिक्त संदर्भ के लिए, नीचे देखें।
क्ले नोट विकिपीडिया से :
[Clang] को GNU कंपाइलर कलेक्शन (GCC) के लिए ड्रॉप-इन रिप्लेसमेंट के रूप में कार्य करने के लिए डिज़ाइन किया गया है, जो इसके अधिकांश संकलन झंडे और अनौपचारिक भाषा एक्सटेंशन का समर्थन करता है।
यह इंगित करने योग्य है कि मुझे लगता है कि यदि आप परिभाषित करते हैं min
और max
तृतीयक के साथ जैसे कि
#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))
तब के विशेष मामले के लिए एक ही परिणाम प्राप्त करने के लिए fmin(-0.0,0.0)
और fmax(-0.0,0.0)
आपको तर्कों को स्वैप करने की आवश्यकता है
fmax(a,b) = MAX(a,b)
fmin(a,b) = MIN(b,a)
fmin(3.0,NaN)==fmin(NaN,3.0)==fmax(3.0,NaN)==fmax(NaN,3.0)==3.0
लगता है Windef.h
(एक ला #include <windows.h>
) के पास max
और min
(निचला मामला) मैक्रोज़ है, जो "दोहरे मूल्यांकन" की कठिनाई से भी पीड़ित हैं, लेकिन वे उन लोगों के लिए हैं जो अपने स्वयं के पुन: रोल नहीं करना चाहते हैं :)
मुझे पता है कि आदमी ने कहा "C" ... लेकिन अगर आपके पास मौका है, तो C ++ टेम्पलेट का उपयोग करें:
template<class T> T min(T a, T b) { return a < b ? a : b; }
सुरक्षित टाइप करें, और अन्य टिप्पणियों में उल्लिखित ++ के साथ कोई समस्या नहीं है।
अधिकतम दो पूर्णांक a
और b
है (int)(0.5((a+b)+abs(a-b)))
। यह भी साथ काम कर सकते (double)
हैं और fabs(a-b)
युगल के लिए (तैरता के लिए समान)
सबसे सरल तरीका यह है कि इसे एक .h
फ़ाइल में एक वैश्विक फ़ंक्शन के रूप में परिभाषित किया जाए , और जब चाहें तब इसे कॉल करें, यदि आपका प्रोग्राम बहुत सारी फ़ाइलों के साथ मॉड्यूलर है। यदि नहीं, double MIN(a,b){return (a<b?a:b)}
तो सबसे सरल तरीका है।
warning: expression with side-effects multiply evaluated by macro
उपयोग के बिंदु पर ...