Handy macros (C)
From LiteratePrograms
This article is a collection of useful C oneliners and macros. Each item in the collection includes some minimal code which demonstrates how the item can be used.
Contents |
Bound a value
Makes sure that value stays within the max - min range. The macro makes use of temporary variables ("TEMP_whatever__
") to avoid possible side effects from evaluating an expression more than once (e.g., i++
increments i
every time it is evaluated).
The logic behind this macro is IF value < MIN THEN value=MIN ELSE (IF value > MAX THEN value=MAX ELSE value=value)
<<macro_bounds.c>>= #include <stdio.h> #define bounds(value, min, max) ((TEMP_VALUE__=(value))>(TEMP_MAX__=(max))?TEMP_MAX__:(TEMP_VALUE__<(TEMP_MIN__=(min))?TEMP_MIN__:TEMP_VALUE__)) int main(void) { int n; int TEMP_VALUE__, TEMP_MAX__, TEMP_MIN__; for(n=0; n<10; n++) { printf("n = %d Adjusted: %d\n", n, bounds(n,3,6)); } return 0; }
Test for even numbers
Check if a non-negative integer is even (2, 4, 6, 8, 10, etc.). It also works for negative integers if the processor represents integers in two's complement form, as is typically the case.
<<macro_iseven.c>>= #include <stdio.h> #define iseven(value) (!((value)&0x01)) int main(void) { int n; for(n=0; n<65; n++) { printf("%d is%s even\n", n, iseven(n)?"":" not"); } return 0; }
Test for powers of two
Check if a positive integer is power of two (2, 4, 8, 16, 32, 64, etc.). The macro makes use of a temporary variable ("TEMP_VALUE__
") to avoid possible side effects from evaluating an expression more than once (e.g., i++
increments i
every time it is evaluated).
<<macro_powoftwo.c>>= #include <stdio.h> #define ispoweroftwo(value) ((TEMP_VALUE__=(value))&&!((TEMP_VALUE__-1)&TEMP_VALUE__)) int main(void) { int n; int TEMP_VALUE__; for(n=0; n<65; n++) { printf("%d is%s power of two\n",n,ispoweroftwo(n)?"":" not"); } return 0; }
Xor swap
Xor swap is an idiom for swapping two variables without using a temporary variable. Generally its use is no longer recommended, as compilers are better able to choose the best swap implementation in a machine-specific way.
<<macro_xorswap.c>>= #include <stdio.h> #define xorswap(a, b) ((a)^=(b),(b)^=(a),(a)^=(b)) int main() { int n1=5; int n2=7; printf("Before xorswap() n1=%d, n2=%d\n", n1, n2); xorswap(n1, n2); printf("After xorswap() n1=%d, n2=%d\n", n1, n2); return 0; }
Set other than 0 to 1
Set all values other than 0 to 1.
<<macro_clamptoone.c>>= #include <stdio.h> #define clamptoone(value) (!!(value)) int main(void) { int n; for(n=0; n<4; n++) { printf("n = %d clamped = %d\n",n,clamptoone(n)); } return 0; }
Download code |