Home > Back-end >  Find the length of pointer chains in C?
Find the length of pointer chains in C?

Time:04-10

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;
}

Try on godbolt

This version handles up to 511 *s. You can easily extend it to more, but the compilation time starts to become excessive.

  •  Tags:  
  • c
  • Related