【问题标题】:C how to access structure elements without using -> repeatedly?C如何在不重复使用->的情况下访问结构元素?
【发布时间】:2020-03-12 15:44:23
【问题描述】:
    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;
}

所以第一个initHeap 看起来很长,因为我必须写很多次heap->。我想让它看起来更短。

一种解决方案是这样写:

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

然后使用tree, pos, p。还有更多方法吗?

【问题讨论】:

  • 抱歉,C 对此没有任何快捷方式。
  • 您当前的 initHeap 对我来说看起来非常好、可读且惯用。
  • 哦,真可惜 :( @NateEldredge 它看起来不错,直到像 heap->tree[heap->pos[i]]
  • 如果你想要Pascal,你可以使用它。不过,即使在 Pascal 中,with 子句也会令人困惑。
  • 请注意,capacity = capacity; 行仅表示如果 with 子句可用时会出现的问题之一 — 是 heap->capacity = capacity;capacity = heap->capacity;heap->capacity = heap->capacity;capacity = capacity;?答案是编译器无法判断 — 必须更改代码,也许参数是 cap 而不是 capacity。它很快就会变得一团糟!

标签: c pointers struct pass-by-reference


【解决方案1】:

您可以使用C99's designated initialiser 语法初始化结构:

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

【讨论】:

  • 这可能最接近 OP 正在寻找的内容。但我认为它不那么惯用。这也意味着整个结构将被初始化(你没有提到的成员为零),如果有不需要初始化的成员,这可能会浪费 CPU 周期。
  • @nate:这当然是我成语的一部分 :-)。确实有一群程序员不愿意使用“新”功能(即只有 20 岁),但也有很多其他人这样做。是的,它确实初始化了整个对象,因此您不能将其用于部分更新。我个人认为初始化整个结构很好;它的成本很低,而且更安全。对于即将被设置为不同值的成员,编译器可能无论如何都能够进行优化。但显然每个人都必须使用自己的判断。
  • 这可以用初始化器以外的函数来完成吗?我在问题中添加了另一个函数。
  • @huy:您可以随意使用它。请记住,构建了一个完整的对象;你不能用它来更新几个成员。正如 Nate 所说,您不必提及每个成员(尽管我经常这样做),因为您未明确命名的成员将被零初始化。
【解决方案2】:

好的旧宏呢?

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 _

如果以规范的方式使用并在此库的实现中使用简洁的代码,我认为这不是一个坏主意。而且,作为奖励,它也适用于部分更新和在 C++ 编译器中导入时(我知道这看起来不是很重要)。

作为旁注,为什么在对malloc() 的调用中使用capacity+1

【讨论】:

  • 嗯,实际上就是这样:D 上面的注释仅适用于初始化程序。另外,容量+1,因为我的实现存储在 1->n 中,树 [0] 作为特殊元素
【解决方案3】:

使用点“。”怎么样? ? 喜欢

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

然后使用

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

【讨论】:

  • 只有当你有一个结构时才有效,而不是指向结构的指针。 .-> 不可互换。在初始化方法中,您将始终拥有一个指针;毕竟,如果他们按值传递它,你就不能初始化调用者的结构。 H 不是在那里对Heap 进行缩写,它声明了一个名为H 的结构的单个实例,这不是一回事。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-01
  • 1970-01-01
  • 2020-07-14
  • 1970-01-01
  • 1970-01-01
  • 2013-08-17
相关资源
最近更新 更多