C - 18 star programming

3 star programming got me thinking - how far can this be taken?? Lets do some 18-star programming!

Now I started fiddling with references in Perl a few years ago, after pointers killed me in college (and I went crawling back to Mechanical Engineering only to end up in IT years later). Now I really want to understand pointers. I have beat around the bush - now its time to beat the bush (and pointers).

So spent some time reading here: Stackoverflow ref 1 and the 5 minute guide to C pointers

And fiddling around by coding up stupid test cases - including structs. In the end, this will probably be a dumping ground for various pointer games.

#include <stdio.h>

/* http://www.codeproject.com/Articles/4894/Pointer-to-Pointer-and-Reference-to-Pointer#3 */

int i; /* read right to left: variable i that is an pointer^n to an int */
int *j;
int **k;
int ***l;
int ****m;
int *****n;
int ******o;
int *******p;
int ********q;
int *********r;
int **********s;
int ***********t;
int ************u;
int *************v;
int **************w;
int ***************x;
int ****************y;
int *****************z;
struct car {
    char *model;
    int n_doors, n_cylinders, year;
    float engine_displacement;
};


void printem (void) {
    printf("i = %d, j = %d, k = %d, l = %d, m = %d, n = %d, o = %d, p = %d, q = %d\n", 
            i, *j, **k, ***l, ****m, *****n, ******o, *******p, ********q);
    printf("r = %d, s = %d, t = %d, u = %d, v = %d, w = %d, x = %d, y = %d, z = %d\n", 
            *********r, **********s, ***********t, ************u, *************v, 
            **************w, ***************x, ****************y, *****************z);
    printf("\n");

}

int main () {


    /* pointer madness on an int */

    j = &i;
    k = &j;
    l = &k;
    m = &l;
    n = &m;
    o = &n;
    p = &o;
    q = &p;
    r = &q;
    s = &r;
    t = &s;
    u = &t;
    v = &u;
    w = &v;
    x = &w;
    y = &x;
    z = &y;

    i = 10;
    printf("i = 10;\n");
    printem();

    *****************z = 11;
    printf("*****************z = 11;\n");
    printem();

    **********s = 12;
    printf("**********s = 12;\n");
    printem();


    /* Pointer madness on a struct */
    /* init array cars to hold 100 struct Car */
    struct car cars[100];

    cars[0].n_doors = 4;
    cars[0].n_cylinders = 6;
    cars[0].engine_displacement = 3.2;
    cars[0].year = 1997;
    cars[0].model = "e320";

    cars[1].n_doors = 4;
    cars[1].n_cylinders = 8;
    cars[1].engine_displacement = 5.0;
    cars[1].year = 1999;
    cars[1].model = "S500 Designo Edition";

    int i;
    int *j;     /* j is a pointer to an int */
    j = &i;     /* j = address-of i */
    struct car *c;  /* c pointer to struct of type car */

    for (i = 0; i <= 1; i++) {
        printf("Car: %s, year: %d, engine: %0.1f, cylinders: %d, n_doors: %d\n", 
            cars[i].model, cars[i].year, cars[i].engine_displacement, 
            cars[i].n_cylinders, cars[i].n_doors);

        /* contents of what j points to, address of (current) car stored in c */
        /* this is the address-of current struct in array of structs */
        c = &(cars[*j]); 
        printf("Car: %s, year: %d, engine: %0.1f, cylinders: %d, n_doors: %d (indirect)\n", 
            c->model, c->year, c->engine_displacement, 
            c->n_cylinders, c->n_doors);
    }

}

Execute and run it...

gcc -Wall -Wuninitialized -o pointermadness pointermadness.c ; ./pointermadness

Here we are seeing the value is set to 10

i = 10;
i = 10, j = 10, k = 10, l = 10, m = 10, n = 10, o = 10, p = 10, q = 10
r = 10, s = 10, t = 10, u = 10, v = 10, w = 10, x = 10, y = 10, z = 10

Now update just "i" or any one of the pointers (the explanations on stackoverflow helped here) and the values are updated. Really, everything resolves down to that one int "i" - so update that one and 18 other things resolve to that value.

*****************z = 11;
i = 11, j = 11, k = 11, l = 11, m = 11, n = 11, o = 11, p = 11, q = 11
r = 11, s = 11, t = 11, u = 11, v = 11, w = 11, x = 11, y = 11, z = 11

**********s = 12;
i = 12, j = 12, k = 12, l = 12, m = 12, n = 12, o = 12, p = 12, q = 12
r = 12, s = 12, t = 12, u = 12, v = 12, w = 12, x = 12, y = 12, z = 12

And for fun - the structs with a pointer to array entry.. Note: I am a Perl data-structure (as well as Perl's Data::Dumper) addict so I really want to know how to manage data structures in C. Additionally, I see a lot of "->" in C code and did not understandd it. I fiddled with it here and the compiler did not like "*c." but wanted "c->". Ah.. that is where it comes from.

So again:

struct car {
    char *model;
    int n_doors, n_cylinders, year;
    float engine_displacement;
};
...
cars[0].n_doors = 4;
cars[0].n_cylinders = 6;
cars[0].engine_displacement = 3.2;
cars[0].year = 1997;
cars[0].model = "e320";

Set up some pointers just to be at least a 1-star programmer:

int i;
int *j;     /* j is a pointer to an int */
j = &i;     /* j = address-of i */
struct car *c;  /* c pointer to struct of type car */

Update "c" in the for loop to the address of the current struct

c = &(cars[*j]); 

And access the current structs' "model" key with:

c->model

And the results - via direct access, or via pointers (stars) are as expected.

Car: e320, year: 1997, engine: 3.2, cylinders: 6, n_doors: 4
Car: e320, year: 1997, engine: 3.2, cylinders: 6, n_doors: 4 (indirect)
Car: S500 Designo Edition, year: 1999, engine: 5.0, cylinders: 8, n_doors: 4
Car: S500 Designo Edition, year: 1999, engine: 5.0, cylinders: 8, n_doors: 4 (indirect)

Published on in