【问题标题】:Structure that mimics two flexible arrays in a struct in C在 C 中的结构中模仿两个灵活数组的结构
【发布时间】:2017-08-13 11:51:50
【问题描述】:

目前,我有一个结构体camera,其中包含两个固定大小的变量fp

struct point {
    double x, y, z;
};

struct camera {
    struct point f[5], p[5];
};

使fp 灵活会导致错误。我遵循了SO question 中给出的说明,并决定使用非结构变量并将它们传递给函数,这导致函数调用语法长且结构混乱。

我的问题虽然是主观的,但是:拥有两个可以通过一个 point 访问的灵活数组(类似于 struct 等)的最佳方法是什么?

【问题讨论】:

  • 并且是static,因此您只能拥有其中一个。
  • 变量总是有固定的大小。
  • 你只关心 same 类型的两个灵活数组吗?数组大小相同?
  • @chux 是的,类型是他们两个的点。
  • 嗯,struct point f[5], p[5]; 看起来你想要struct point 类型而不是double

标签: c data-structures struct


【解决方案1】:

一种非灵活数组方法遵循,IMO,使用一对更干净的struct point指针解决了OP的“长函数调用语法和混乱结构”的更高级别问题。

struct camera {
    size_t size;  // add size member
    struct point *f;
    struct point *p;
};

bool camera_initialize(struct camera *cam, size_t size) {
  // Use 1 or 2 allocations
  cam->f = malloc(sizeof *(cam->f) * 2 * size);
  if (cam->f) {
    cam->p = cam->f + size;
    cam->size = size;
    return false; // success 
  } else {
    cam->p = cam->f = NULL;
    cam->size = 0;
    return size > 0; // fail if size was not 0
  }
}

void camera_uninitialize(struct camera *cam) {
  free(cam->f);
  cam->p = cam->f = NULL;
  cam->size = 0;
}

示例用法

int main() {
  size_t n  = foo();
  struct camera cam;
  if (camera_initialize(&cam, n)) return EXIT_FAILURE;
  bar(cam.f, cam.n);
  bar(cam.p, cam.n);
  camera_uninitialize(&cam);
}

【讨论】:

  • @sitilge 是更正的代码应该做free(cam->f); Post 修改。
【解决方案2】:

根据定义,您不能有两个灵活的数组成员。一个灵活的数组成员必须是结构中的最后一个,只能有一个“last”元素。

但我感觉您显然需要配对 fp,那么为什么不将它们聚合起来呢?然后你可以拥有这些对的灵活数组成员:

#include <stdio.h>
#include <stdlib.h>

struct point {
    double x, y, z;
};

struct camera {
    char dummy;
    struct {
        struct point f, p;
    } pairs[];
};

int main(void) {
    struct camera *c = malloc(sizeof(*c) + sizeof(c->pairs[0])*5);

    return 0;
}

注意 C99 对灵活数组成员的支持的使用。

【讨论】:

    【解决方案3】:

    这是一种模拟两个相同类型的灵活数组的方法:创建一个包含两个数组的灵活数组,并在第二个灵活数组开始的位置向数组中添加一个指针:

    struct camera {
        struct point *p;
        struct point f[];
    };
    

    分配camera 时,为两个数组提供空间,并将其添加到“原始”sizeof(struct camera)。假设您的第一个数组有n 元素,第二个数组有m。然后你初始化你的camera如下:

    struct camera *c = malloc(sizeof(*c)+(n+m)*sizeof(struct point));
    c->p = &(c->f[n]); // Point "p" to the beginning of the second array
    for (int i = 0 ; i != n ; i++) {
        c->f[i] = ... // Init points in f
    }
    for (int i = 0 ; i != m ; i++) {
        c->p[i] = ... // Init points in p
    }
    

    【讨论】:

    • 不应该是struct point *p;吗? (顺便说一句,我没有投反对票或投赞成票)
    猜你喜欢
    • 1970-01-01
    • 2011-03-04
    • 2013-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多