I'm dabbling with pointers in C and created a Pac-Man Inky pointer example.
int
********
****************
****************
********************
********************
******* * ** * *******
******* ** *******
******* ** *******
************************
****************************
****************************
****************************
****************************
****************************
****************************
**** ****** ****** ****
**** ****** ****** ****
** **** **** **
** **** **** **
inky;
Question
Is there a way to programmatically determine the Inky pointer chain length (currently 386)?
CodePudding user response:
I don't think there is a way to do it for a completely arbitrary number of *
, but if you have a fixed maximum number, you can write a long _Generic
selection to do it.
#define COUNT_STARS(p) \
_Generic(p, \
int : 0, \
int * : 1, \
int ** : 2, \
/* etc.... */ \
)
And you can use preprocessor tricks to generate such a macro using only O(log2(n)) lines of source code:
#include <stdio.h>
#define PTR0 *
#define PTR1 PTR0 PTR0
#define PTR2 PTR1 PTR1
#define PTR3 PTR2 PTR2
#define PTR4 PTR3 PTR3
#define PTR5 PTR4 PTR4
#define PTR6 PTR5 PTR5
#define PTR7 PTR6 PTR6
#define PTR8 PTR7 PTR7
#define GEN0(T, stars, n) T stars : (n)
#define GEN1(T, stars, n) GEN0(T, stars, (n)) , GEN0(T, stars PTR0 , (n) (1 << 0))
#define GEN2(T, stars, n) GEN1(T, stars, (n)) , GEN1(T, stars PTR1 , (n) (1 << 1))
#define GEN3(T, stars, n) GEN2(T, stars, (n)) , GEN2(T, stars PTR2 , (n) (1 << 2))
#define GEN4(T, stars, n) GEN3(T, stars, (n)) , GEN3(T, stars PTR3 , (n) (1 << 3))
#define GEN5(T, stars, n) GEN4(T, stars, (n)) , GEN4(T, stars PTR4 , (n) (1 << 4))
#define GEN6(T, stars, n) GEN5(T, stars, (n)) , GEN5(T, stars PTR5 , (n) (1 << 5))
#define GEN7(T, stars, n) GEN6(T, stars, (n)) , GEN6(T, stars PTR6 , (n) (1 << 6))
#define GEN8(T, stars, n) GEN7(T, stars, (n)) , GEN7(T, stars PTR7 , (n) (1 << 7))
#define GEN9(T, stars, n) GEN8(T, stars, (n)) , GEN8(T, stars PTR8 , (n) (1 << 8))
#define COUNT_STARS(T, expr) _Generic(expr, GEN9(T, , 0))
int
********
****************
****************
********************
********************
******* * ** * *******
******* ** *******
******* ** *******
************************
****************************
****************************
****************************
****************************
****************************
****************************
**** ****** ****** ****
**** ****** ****** ****
** **** **** **
** **** **** **
inky;
int main(void) {
printf("%d\n", COUNT_STARS(int, inky));
return 0;
}
This version handles up to 511 *
s. You can easily extend it to more, but the compilation time starts to become excessive.