সি MIN
এবং কোথায় MAX
সংজ্ঞায়িত করা হয়, যদি আদৌ?
এগুলি বাস্তবায়নের সর্বোত্তম উপায় কোনটি, সাধারণভাবে এবং যথাসম্ভব নিরাপদে টাইপ করুন? (মূলধারার সংকলকগুলির জন্য সংকলক বর্ধিতকরণ / বিল্টিনগুলি পছন্দসই))
সি MIN
এবং কোথায় MAX
সংজ্ঞায়িত করা হয়, যদি আদৌ?
এগুলি বাস্তবায়নের সর্বোত্তম উপায় কোনটি, সাধারণভাবে এবং যথাসম্ভব নিরাপদে টাইপ করুন? (মূলধারার সংকলকগুলির জন্য সংকলক বর্ধিতকরণ / বিল্টিনগুলি পছন্দসই))
উত্তর:
সি
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
যাইহোক সি ++ হয়), অর্থাত্ জিসিসির ({ ... })
সিনট্যাক্স তাই আমি নিশ্চিত যে এটি কোনওভাবেই সম্ভব নয়। আমি এই সমস্যা সম্পর্কিত অন্য কোনও সংকলকের দিকে নজর
MAX(someUpperBound, someRandomFunction())
এলোমেলো মানকে কিছু উচ্চ স্তরের সীমাবদ্ধ করার জন্য করেছিল। এটি একটি ভয়ানক ধারণা ছিল, তবে এটি এমনকি কার্যকরও হয়নি, কারণ MAX
তিনি যে ব্যবহার করছিলেন তার দ্বিগুণ মূল্যায়নের সমস্যা ছিল, তাই প্রাথমিকভাবে যা মূল্যায়ন করা হয়েছিল তার চেয়ে আলাদা এলোমেলো সংখ্যার সাথে তিনি শেষ করেছেন।
MIN(x++, y++)
তবে প্রিপ্রসেসর নীচের কোডটি উত্পন্ন করবে (((x++) < (y++)) ? (x++) : (y++))
। সুতরাং, x
এবং y
দুবার বৃদ্ধি করা হবে।
এটি জিএনইউ লিবিসি (লিনাক্স) এবং সায়স / প্যারাম এইচএস এর ফ্রিবিএসডি সংস্করণগুলিতেও সরবরাহ করা হয়েছে এবং স্বপ্নাদলক্ষীর দ্বারা সরবরাহ করা সংজ্ঞা রয়েছে।
দেবিয়ান:
$ 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.
ফ্রিবিএসডি তে:
$ 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
আছে, কিন্তু আফাইক, সি স্ট্যান্ডার্ড লাইব্রেরিতে কোনও সমতুল্য নেই। এগুলি আপনি ম্যাক্রোগুলির মতো নিজের সাথে সংজ্ঞায়িত করতে পারেন
#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
প্রাধান্যের কারণে পার্স করে । প্রোগ্রামার সম্ভবত এটি করতে চেয়েছিলেন তা নয়।
অ-মানক সংকলক এক্সটেনশনগুলি এড়িয়ে চলুন এবং খাঁটি স্ট্যান্ডার্ড সি (আইএসও 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 ম্যাক্রো কল করা হবে। প্রতিটি ম্যাক্রো প্যারামিটারের চারপাশে অতিরিক্ত প্রথম বন্ধনী প্রয়োজন, সি ম্যাক্রো লেখার সময় সাধারণ মানক সতর্কতা হিসাবে।
তারপরে সিটিতে অন্তর্নিহিত ধরণের প্রচারের ক্ষেত্রে স্বাভাবিক সমস্যা রয়েছে ?:
অপারেটর একে অপরের বিপরীতে 2 য় এবং 3 য় অপারেন্ডকে ভারসাম্যপূর্ণ করে। উদাহরণস্বরূপ, ফলাফল 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__
'ক্লিন' আইএসও সি-র জন্য গ্রহণ করেছে - জিসিসি -৪.৯-এর মতো আরও ভাল সমাধান পাওয়া যায় ।
#define max(x,y) ( \
{ __auto_type __x = (x); __auto_type __y = (y); \
__x > __y ? __x : __y; })
এই এক্সটেনশনের সুস্পষ্ট সুবিধা হ'ল __typeof__
সমাধানের বিপরীতে প্রতিটি ম্যাক্রো যুক্তি কেবল একবার প্রসারিত হয় ।
__auto_type
সি ++ 11 এর একটি সীমাবদ্ধ ফর্ম auto
। এটি সি (+ না হওয়া উচিত?) সি ++ কোডে ব্যবহার করা যাবে না, যদিও auto
সি ++ 11 ব্যবহারের ক্ষেত্রে উচ্চতর প্রকারের অনুমানের ক্ষমতাগুলি ব্যবহার না করার কোনও ভাল কারণ নেই ।
এটি বলেছিল, আমি ধরে নিয়েছি যে ম্যাক্রো কোনও extern "C" { ... }
সুযোগে অন্তর্ভুক্ত করার সময় এই সিনট্যাক্সটি ব্যবহার করার কোনও সমস্যা নেই ; যেমন, একটি সি শিরোনাম থেকে। আফাইক, এই এক্সটেনশানটি তার উপায় তথ্য বিড়ম্বনা খুঁজে পায় নি
c-preprocessor
ট্যাগ রয়েছে। জিসিসির __always_inline__
বৈশিষ্ট্যের মতো কিছু ব্যবহার না করা পর্যন্ত কোনও ক্রিয়াকলাপটি কথ্য কীওয়ার্ডের সাথেও অন্তর্ভুক্ত হওয়ার নিশ্চয়তা নেই ।
আমি এই সংস্করণটি লিখেছি যা এমএসভিসি, জিসিসি, সি, এবং সি ++ এর জন্য কাজ করে।
#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: সি এবং সি ++ উভয় শেখার জন্য বা এক থেকে অন্যটিতে রূপান্তরকারীদের জন্য মূল্যবান তুলনা হিসাবে, আমি কীভাবে সি ++ টেম্পলেটগুলির সাথে এটি কীভাবে করা হবে তা দেখানোর জন্য আমি একটি বিভাগ 3 যুক্ত করেছি। আমি এই উত্তরটি বারবার ফিরে আসতে পারলাম এমন একটি প্রচলিত রেফারেন্স তৈরির জন্য পুরোপুরি এবং সত্যবাদী এবং সঠিক হওয়ার জন্য যথাসাধ্য চেষ্টা করেছি এবং আমি আশা করি আপনি এটি আমার মতো কার্যকর পেয়েছেন।
এই কৌশলটি সাধারণত ব্যবহৃত হয়, যারা সঠিকভাবে এটি কীভাবে ব্যবহার করতে জানে, "ডি ফ্যাক্টো" জিনিসগুলি করার পদ্ধতি এবং সঠিকভাবে যদি ব্যবহার করা হয় তবে সঠিকভাবে ব্যবহার করা ভাল, তবে আপনি বগি (মনে করুন: ডাবল-মূল্যায়ন পার্শ্ব প্রতিক্রিয়া ) যদি আপনি ব্যবহার করেন তবে তুলনা করতে ভেরিয়েবল অ্যাসাইনমেন্ট সহ এক্সপ্রেশনগুলি সর্বদা পাস করুন:
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define MIN(a,b) ((a) < (b) ? (a) : (b))
এই কৌশলটি উপরের "ডাবল-মূল্যায়ন" পার্শ্ব প্রতিক্রিয়া এবং বাগগুলি এড়িয়ে চলে এবং তাই এটি করার জন্য সেরা, নিরাপদ এবং "আরও আধুনিক" জিসিসি সি উপায় হিসাবে বিবেচিত হয় । এটি জিসিসি এবং ক্ল্যাং সংকলক উভয়ের সাথেই কাজ করার প্রত্যাশা করুন, যেহেতু ক্ল্যাংটি ডিজাইনের মাধ্যমে, জিসিসি-সামঞ্জস্যপূর্ণ (এই উত্তরের নীচে ক্ল্যাং নোটটি দেখুন)।
বাট: "নজর রাখুন" চলক ছায়াময় " প্রভাবগুলি এখনও , কারণ বিবৃতি প্রকাশগুলি স্পষ্টতই অন্তর্নিহিত রয়েছে এবং সেইজন্য তাদের নিজস্ব স্থানীয় পরিবর্তনশীল সুযোগ নেই!
#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; \
})
নোট করুন যে সিসি স্টেটমেন্ট এক্সপ্রেশনগুলিতে কোড ব্লকের সর্বশেষ এক্সপ্রেশনটি হ'ল এক্সপ্রেশন থেকে "ফিরে", যেন এটি কোনও ফাংশন থেকে ফিরে এসেছে।জিসিসির ডকুমেন্টেশন এটিকে এভাবে বলে:
যৌগিক বিবৃতিতে শেষ জিনিসটি সেমিকোলন দ্বারা অনুসরণ করা একটি অভিব্যক্তি হওয়া উচিত; এই subexpression এর মান পুরো কনস্ট্রাক্টের মান হিসাবে কাজ করে। (যদি আপনি বন্ধনীগুলির মধ্যে শেষ পর্যন্ত অন্য কোনও ধরণের বিবৃতি ব্যবহার করেন তবে কনস্ট্রাক্টের টাইপটি বাতিল শূন্য রয়েছে এবং ফলস্বরূপ কার্যকরভাবে কোনও মূল্য নেই))
সি ++ দ্রষ্টব্য: যদি সি ++ ব্যবহার করেন তবে পরিবর্তে এই ধরণের নির্মাণের জন্য টেমপ্লেটগুলি সম্ভবত সুপারিশ করা হয়, তবে আমি ব্যক্তিগতভাবে টেম্পলেটগুলি অপছন্দ করি এবং সম্ভবত সি ++ তে উপরের একটি নির্মাণ ব্যবহার করব, কারণ আমি প্রায়শই এম্বেড থাকা সি ++ তেও সি স্টাইলগুলি পছন্দ করি এবং পছন্দ করি।
এই বিভাগে 25 এপ্রিল যোগ করা হয়েছে 2020:
আমি গত কয়েক মাস ধরে একটি টন সি ++ করছি এবং সি ++ সম্প্রদায়ের যেখানে ম্যাক্রোগুলির তুলনায় টেমপ্লেটগুলি পছন্দ করার চাপ রয়েছে তা বেশ শক্তিশালী। ফলস্বরূপ, আমি টেমপ্লেটগুলি ব্যবহার করে আরও ভাল হয়ে উঠছি এবং সম্পূর্ণতার জন্য এখানে সি ++ টেম্পলেট সংস্করণগুলি যুক্ত করতে চাই এবং এটি আরও যুক্তিযুক্ত এবং পুঙ্খানুপুঙ্খ উত্তর করতে চাই।
এখানে কি মৌলিক এর ফাংশন টেমপ্লেট সংস্করণ 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;
}
সি ++ টেম্পলেট সম্পর্কে এখানে অতিরিক্ত পাঠ করুন: উইকিপিডিয়া: টেমপ্লেট (সি ++) ।
যাইহোক, উভয়ই max()
এবং min()
ইতিমধ্যে <algorithm>
হেডারে ( #include <algorithm>
) , সি ++ স্ট্যান্ডার্ড লাইব্রেরির অংশ । সি ++ স্ট্যান্ডার্ড লাইব্রেরিতে এগুলি আমার উপরের তুলনায় কিছুটা আলাদাভাবে সংজ্ঞায়িত করা হয়েছে। ডিফল্ট এগুলির নমুনা 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
সি ++ ফাংশনের সংকলন-সময় দিকটি এটিকে সি-ম্যাক্রোর মতো করে তোলে, যদি কোনও constexpr
ফাংশনের জন্য যদি সংকলন-সময় মূল্যায়ন সম্ভব হয় তবে এটি সংকলন-সময়ে করা হবে, একই MIN()
বা একই হিসাবেMAX()
ম্যাক্রো প্রতিকল্পন সম্ভবত পারা সি বা সি ++ তেও কমপাইল সময়ে সম্পূর্ণ মূল্যায়ন করা হবে। এই সি ++ টেম্পলেট তথ্যের জন্য অতিরিক্ত রেফারেন্সের জন্য, নীচে দেখুন।
উইকিপিডিয়া থেকে কলঙ্ক নোট :
[ঝাঁকুনি] GNU সংকলক সংগ্রহের জন্য একটি ড্রপ-ইন প্রতিস্থাপন হিসাবে কাজ করার জন্য ডিজাইন করা হয়েছে (জিসিসি), এর বেশিরভাগ সংকলন পতাকা এবং বেসরকারী ভাষা বর্ধনকে সমর্থন করে।
এটি উল্লেখ করা মূল্যবান আমি মনে করি যে আপনি যদি সংজ্ঞায়িত করেন 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
এটি "ডাবল মূল্যায়ন" অসুবিধায় ভুগছে, তবে তারা তাদের জন্য রয়েছে যারা নিজের পুনরায় রোল করতে চান না :)
আমি জানি লোকটি "সি" বলেছিল ... তবে আপনার যদি সুযোগ হয় তবে একটি সি ++ টেম্পলেট ব্যবহার করুন:
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
ব্যবহারের জায়গায় ...