C:指向函数中结构内部结构数组的指针

C:指向函数中结构内部结构数组的指针,c,arrays,pointers,struct,C,Arrays,Pointers,Struct,我对C相当陌生。我创建了一个结构和一组结构来存储数据,并将它们分别传递给我的函数: int dosomething(struct s1 *struct1, struct s2 *struct2); struct S1 { int a; int b; int c; }; struct S2 { double x; double y; double z; }; int main() { int n = 200; struct S

我对C相当陌生。我创建了一个结构和一组结构来存储数据,并将它们分别传递给我的函数:

int dosomething(struct s1 *struct1, struct s2 *struct2);

struct S1 {
    int a;
    int b;
    int c;
};

struct S2 {
    double x;
    double y;
    double z;
};


int main()
{
    int n = 200;
    struct S1 s1;
    struct S2 *s2 = malloc(n * sizeof(struct S2));

    dosomething(&s1, &s2[0])

    return 0;
}

int dosomething(struct S1 *s1, struct S2 *s2)
{
    s1->a = 1;
    s1->b = 2;
    s1->c = 3;

    s2[0].x = 1.1;
    s2[1].x = 1.123233;
    ...

    return 1;
}
struct StuffParameters parameters = { &s1, &s2, &s3 };

do_stuff(&parameters);
do_some_other_stuff(&parameters);
yet_another_function(&parameters);
随着时间的推移,这变得很烦人,所以我决定把它们放在一起。 现在我正在这样做

struct S1 {
    int a;
    int b;
    int c;
    struct S2 *s2;
};

struct S2 {
    double x;
    double y;
    double z;
};


int main()
{
    int n = 200;
    struct S1 s1;
    struct S2 *s2 = malloc(n * sizeof(struct S2));
    s1.s2 = s2;

    dosomething(&s1)

    return 0;
}


int dosomething(struct S1 *s1)
{
    s1->a = 1;
    s1->b = 2;
    s1->c = 3;

    s1->s2[0].x = 1.1;
    s1->s2[1].x = 1.123233;
    ...

    // OR

    struct S2 *s2 = s1->s2;
    s2[0].x = 1.1;
    s2[1].x = 1.123233;
    ...
}
现在,问题是: 我读了很多关于指向结构、数组、结构数组等的指针的书,但我仍然不确定我在这里所做的是否正确。 , , , . 我的项目规模越来越大,我只是不想让它变得更糟

我需要创建一个指向s2.s1[x]的指针数组吗

我需要告诉一个指针(struct S2*S2=s1->S2)S2有多少元素吗


是否存在任何陷阱或可能出现问题?

它没有任何问题,问题在于它是否符合您的要求,并且从长远来看,它是一个不错的设计选择

另外,你也可以这样做

s1.s2 = malloc(sizeof *s1.s2);
if (s1.s2 == NULL)
    error_handler(); // do not use s1.s2 after this
dosomething(&s1);

它没有什么问题,这是一个是否符合您的要求的问题,从长远来看,它是一个很好的设计选择

另外,你也可以这样做

s1.s2 = malloc(sizeof *s1.s2);
if (s1.s2 == NULL)
    error_handler(); // do not use s1.s2 after this
dosomething(&s1);

将结构、指针或数组放置在另一个结构中称为组合。如果
S2
数组属于
S1
struct,则应将其放置在
S2
数组中

例如,
是一对
(x,y)
坐标,因此很明显,它应该由两个
int
s组成,即:

void do_stuff(struct Point pt);
优于:

void do_stuff(int x, int y);
但千万不要仅仅因为你想节省一些打字时间就这样做。如果
S2
适合
S1
内部,如果程序中没有
S1
而没有
S2
,则可以这样做

因此,如果这两个结构不属于一起,但您发现自己将相同的参数序列传递给多个函数,那么您可以使用一种称为的OOP重构技术变体。也就是说,不要这样做:

do_stuff(&s1, &s2, &s3);
您可以创建一个新结构,该结构除了由以下参数组成外,没有其他用途:

struct StuffParameters {
    struct S1 * s1;
    struct S2 * s2;
    struct S3 * s3;
};
然后您可以将其传递给多个“类似”函数:

int dosomething(struct s1 *struct1, struct s2 *struct2);

struct S1 {
    int a;
    int b;
    int c;
};

struct S2 {
    double x;
    double y;
    double z;
};


int main()
{
    int n = 200;
    struct S1 s1;
    struct S2 *s2 = malloc(n * sizeof(struct S2));

    dosomething(&s1, &s2[0])

    return 0;
}

int dosomething(struct S1 *s1, struct S2 *s2)
{
    s1->a = 1;
    s1->b = 2;
    s1->c = 3;

    s2[0].x = 1.1;
    s2[1].x = 1.123233;
    ...

    return 1;
}
struct StuffParameters parameters = { &s1, &s2, &s3 };

do_stuff(&parameters);
do_some_other_stuff(&parameters);
yet_another_function(&parameters);

将结构、指针或数组放置在另一个结构中称为组合。如果
S2
数组属于
S1
struct,则应将其放置在
S2
数组中

例如,
是一对
(x,y)
坐标,因此很明显,它应该由两个
int
s组成,即:

void do_stuff(struct Point pt);
优于:

void do_stuff(int x, int y);
但千万不要仅仅因为你想节省一些打字时间就这样做。如果
S2
适合
S1
内部,如果程序中没有
S1
而没有
S2
,则可以这样做

因此,如果这两个结构不属于一起,但您发现自己将相同的参数序列传递给多个函数,那么您可以使用一种称为的OOP重构技术变体。也就是说,不要这样做:

do_stuff(&s1, &s2, &s3);
您可以创建一个新结构,该结构除了由以下参数组成外,没有其他用途:

struct StuffParameters {
    struct S1 * s1;
    struct S2 * s2;
    struct S3 * s3;
};
然后您可以将其传递给多个“类似”函数:

int dosomething(struct s1 *struct1, struct s2 *struct2);

struct S1 {
    int a;
    int b;
    int c;
};

struct S2 {
    double x;
    double y;
    double z;
};


int main()
{
    int n = 200;
    struct S1 s1;
    struct S2 *s2 = malloc(n * sizeof(struct S2));

    dosomething(&s1, &s2[0])

    return 0;
}

int dosomething(struct S1 *s1, struct S2 *s2)
{
    s1->a = 1;
    s1->b = 2;
    s1->c = 3;

    s2[0].x = 1.1;
    s2[1].x = 1.123233;
    ...

    return 1;
}
struct StuffParameters parameters = { &s1, &s2, &s3 };

do_stuff(&parameters);
do_some_other_stuff(&parameters);
yet_another_function(&parameters);

您的编译器是否显示任何警告?关于
main()
的隐式声明?定义了
n
的位置?您需要指针包含的元素数。@BLUEPIXY True,它可能是另一个结构成员。@dimplemind:最好是1。把这个贴上,然后2。使用您的实际代码(这是代码审查的一个要求)。使用像S1和S2这样的模糊名称使代码检查和合理建议变得非常不可能。编译器是否显示任何警告?关于
main()
的隐式声明?定义了
n
的位置?您需要指针包含的元素数。@BLUEPIXY True,它可能是另一个结构成员。@dimplemind:最好是1。把这个贴上,然后2。使用您的实际代码(这是代码审查的一个要求)。使用像S1和S2这样的模糊名称使代码审查和合理建议变得非常不可能。好吧,一开始我不知道如何将结构放在一起,我想让代码运行。但他们属于一起。“引入参数对象”看起来很有趣。我必须记住这一点。@dimplemind:“引入参数对象”(虽然C不是面向对象的)的想法比最初看起来要酷一些,因为它允许您在一个单独的“模块”中提取与这组参数相关的所有函数,同时仍然让这些结构在逻辑上独立于有意义的函数。C++中,所有这些新的“参数对象”的函数都是它的单独类的成员。但同样,如果您发布一段实际的代码来澄清这些结构实际上代表了什么,那就更好了。现在已经太晚了。我马上就走。也许明天我至少会发布相关部分。好吧,一开始我不知道如何把结构放在一起,我想让代码运行。但他们属于一起。“引入参数对象”看起来很有趣。我必须记住这一点。@dimplemind:“引入参数对象”(虽然C不是面向对象的)的想法比最初看起来要酷一些,因为它允许您在一个单独的“模块”中提取与这组参数相关的所有函数,同时仍然让这些结构在逻辑上独立于有意义的函数。C++中,所有这些新的“参数对象”的函数都是它的单独类的成员。但同样,如果您发布一段实际的代码来澄清这些结构实际上代表了什么,那就更好了。现在已经太晚了。我马上就走。也许明天我至少会发布相关部分。