简体   繁体   中英

C how to access structure elements without using -> repeatedly?

    struct Heap {
        int capacity;
        int heapSize;
        int *tree;     // the heap binary tree
        int *pos;       // pos[i] is the position of values[i] in items
        float *p;  // priority value of each heap element
    };

    void initHeap(struct Heap *heap, int capacity) {
        heap->capacity = capacity;
        heap->heapSize = 0;
        heap->tree = malloc(sizeof(int)*(capacity+1));
        heap->pos = malloc(sizeof(int)*(capacity+1));
        heap->p = malloc(sizeof(float)*(capacity+1));
    }

    void betterInit(struct Heap *heap, int capacity) {
        with (heap) { // doesn't exist
            capacity = capacity;
            heapSize = 0;
            tree = malloc(sizeof(int)*(capacity+1));
            pos = malloc(sizeof(int)*(capacity+1));
            p = malloc(sizeof(float)*(capacity+1));
        }
    }
// update heap after a value is increased
void upHeap(struct Heap *heap, int i) {
    int *tree = heap->tree, *pos = heap->pos;
    float *p = heap->p;
    int c, r;

    c = pos[i];         // position of element i-th in heap
    while (true) {
        r = parent(c);
        if (r==0 || p[tree[r]] >= p[i]) break; // if c is root, or priority(parent(c)) is > priority(c)
        pos[tree[r]] = c;  // pull the parent down to c
        tree[c] = tree[r];
        c = r;
    }
    tree[c] = i;
    pos[i] = c;
}

So the 1st initHeap looks long because I have to write heap-> a lot of times. And I wish to make it look shorter.

One solution is to write:

int *tree = heap->tree;
int *pos = heap->pos;
float *p = heap->p;

and then use tree, pos, p . Are there more ways?

You can initialise a struct using C99's designated initialiser syntax:

void initHeap(struct Heap *heap, int capacity) {
    *heap = (struct Heap){
        .capacity = capacity,
        .heapSize = 0,
        .tree = malloc(sizeof(int)*(capacity+1)),
        .pos = malloc(sizeof(int)*(capacity+1)),
        .p = malloc(sizeof(float)*(capacity+1))
    };
}

What about good old macros?

struct Heap {
    int capacity;
    int heapSize;
    int *tree;     // the heap binary tree
    int *pos;       // pos[i] is the position of values[i] in items
    float *p;  // priority value of each heap element
};

#define _(x) heap->x
void initHeap(struct Heap *heap, int capacity) {
    _(capacity) = capacity;
    _(heapSize) = 0;
    _(tree) = malloc(sizeof(int)*(capacity+1));
    _(pos) = malloc(sizeof(int)*(capacity+1));
    _(p) = malloc(sizeof(float)*(capacity+1));
}
/* More struct Heap related functions */
#undef _

If used in a disciplined way and for having terse code in the implementation of this library, I don't find it such a bad idea. And, as a bonus, it works also for partial updates and when imported in C++ compilers (I know this doesn't look very significant).

As a side comment, why the capacity+1 in the calls to malloc() ?

How about using a dot "." ? Like

struct Heap {
    int capacity;
    int heapSize;
    int *tree;     // the heap binary tree
    int *pos;       // pos[i] is the position of values[i] in items
    float *p;  // priority value of each heap element
}H; //to make abbreviation for Heap

then use

H.capacity = capacity;
H.heapsize = 0;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM