2つの数値のうち小さい方を返すために、#defineを使用して単純なマクロを作成したいと思います。
Cでこれを行うにはどうすればよいですか?いくつかのアイデアを提案し、それをもっと難解にすることができるかどうかを確認してください。
2つの数値のうち小さい方を返すために、#defineを使用して単純なマクロを作成したいと思います。
Cでこれを行うにはどうすればよいですか?いくつかのアイデアを提案し、それをもっと難解にすることができるかどうかを確認してください。
通常:
#define min(a, b) (((a) < (b)) ? (a) : (b))
これは最小値を 2 回評価することに注意してください。
しかし、なぜ難読化する必要があるのでしょうか。
これは結果を変数に格納し、各引数を一度だけ評価します。これは基本的に、貧弱なインライン関数 + 宣言です。
#define min(t, x, a, b) \
t x; \
{ \
t _this_is_a_unique_name_dont_use_it_plz_0_ = a; \
t _this_is_a_unique_name_dont_use_it_plz_1_ = b; \
x = _this_is_a_unique_name_dont_use_it_plz_0_ < \
_this_is_a_unique_name_dont_use_it_plz_1_ ? \
_this_is_a_unique_name_dont_use_it_plz_0_ : \
_this_is_a_unique_name_dont_use_it_plz_1_ ; \
}
次のように使用します。
min(int, x, 3, 4)
/* x is an int, equal to 3
Just like doing:
int x = min(3, 4);
Without double evaluation.
*/
そして、念のため、GNU C の例を示します。
#define MAX(a,b) ({ \
typeof(a) _a_temp_; \
typeof(b) _b_temp_; \
_a_temp_ = (a); \
_b_temp_ = (b); \
_a_temp_ = _a_temp_ < _b_temp_ ? _b_temp_ : _a_temp_; \
})
難読化されていませんが、これは任意のタイプ、任意のコンテキスト、任意の引数など (ほとんどのコメントを参照) で機能すると思います。反例が思いつく場合は修正してください。
この方法はかなりかわいいと思います。
#define min(a, b) (((a) + (b) - fabs((a) - (b))) * 0.5)
確かに、これには #define を使用できますが、なぜそうしたいのでしょうか? #define を使用する際の問題は、括弧を使用しても、このようなコードで予期しない結果が得られることです (実際にこれを行うことはありませんが、問題を示しています)。
int result = min(a++, b++);
C ではなく C++ を使用している場合は、インライン関数を使用することをお勧めします。これは、(i) パラメーターを複数回評価することを回避し、(ii) タイプ セーフです (unsigned など、他のタイプの値を取るバージョンを提供することもできます)。 、倍精度または文字列)。
inline int min(int a, int b) { return (a < b) ? a : b; }
これを少し難読化しようとすると、おそらく次のようなものになります。
#define min(a,b) ((a) + ((b) < (a) ? (b) - (a) : 0))
Doynaxのソリューションもかなりかわいいと思います。マクロ引数が複数回評価されることについての両方の通常の予約。
少し難読化するには、これを試してください:
#define MIN(a,b) ((((a)-(b))&0x80000000) >> 31)? (a) : (b)
基本的に、それらを減算し、符号ビットを 1 または 0 と見なします。減算の結果が負の数になる場合、最初のパラメーターは小さくなります。