【问题标题】:Initialize struct variable with previous one C [closed]用前一个C初始化结构变量[关闭]
【发布时间】:2018-01-22 12:14:11
【问题描述】:

我想要一个如下结构:

typedef struct Mystruct
{
    double  p;
    double  x_min;
    double  x_max;
    double y_min;
    double y_max;
    double params[] = {x_min, x_max, y_min, y_max};
 };

我的目标是数组params 的元素应该由{ x_min, x_max, y_min, y_max} 填充。

有没有办法在中实现这个结构?

【问题讨论】:

  • 你可以在初始化所有 x_*y_* 自己时这样做......
  • 为什么?使用嵌套结构,获取指针,然后使用内部地址填充指针。
  • 为什么? XY 问题气味。
  • @n.m. - 从字面上看是一个 XY 问题:D
  • 您的代码是在声明和定义一个结构,而不是初始化它。这是主要问题。第二个问题是不必要的数据重复。

标签: c c arrays struct


【解决方案1】:

在 C 中你不能这样做,相反你可以编写一个函数来初始化结构实例。

typedef struct Mystruct
{
        double  p;
        double  x_min;
        double  x_max;
        double y_min;
        double y_max;
        double params[4];
}Mystruct;


Mystruct GetMystruct( double p, 
                      double x_min, 
                      double x_max, 
                      double y_min, 
                      double y_max)
{
    Mystruct my = { p, x_min,x_max,y_min,y_max, {x_min,x_max,y_min,y_max} } ;

    return my;
}

然后,例子:

Mystruct m = GetMystruct( 0.0, 42.1, 42.2, 42.3,42.4 );

【讨论】:

    【解决方案2】:

    如果您的意图是对同一结构成员有两个不同的视图,一个按名称,一个按索引,那么这可以在大多数 C 实现中实现:

    #include <stdio.h>
    
    
    typedef struct foo
    {
        double p;
        union
        {
            struct { double x_min, x_max, y_min, y_max; };
            double params[4];
        };
    } foo;
    
    
    int main(void)
    {
        foo x = { 1, 2, 3, 4, 5 };
        for (size_t i = 0; i < 4; ++i)
            printf("%g\n", x.params[i]);
    }
    

    这有一些理论上的危险(特别是确保内部 struct 没有被填充),但它可以在正常的 C 实现中工作,并且可以防范这些危险。 (检查内部 struct 的大小是否等于数组的大小将防止填充。为了检查大小,您需要给 struct 一个标签,以便它有一个名称。)

    这使用联合使命名成员与数组元素相同(不仅仅是初始化为相同,而是实际使用相同的成员),它使用匿名structunion 使内部聚合中的成员名称可用作外部struct. 的成员名称

    【讨论】:

      【解决方案3】:

      可以使用union 在 XY 参数和数组中的条目之间共享内存:

      typedef struct Mystruct
      {
         double  p;
         union {
            struct {
               double  x_min;
               double  x_max;
               double y_min;
               double y_max;
            };
            double params[] = {x_min, x_max, y_min, y_max};
      };
      

      这意味着 xy 值将始终与数组中的值相同

      【讨论】:

        【解决方案4】:

        不,你不能这样做。您不能在结构声明中初始化成员。 因为结构声明定义了类型而不是变量。你展示的方式。保留一组相互依赖的变量。就算你能,你为什么要那样做?只需有一个数组。

        typedef struct Mystruct
        {
                double  p;
                double params[4];
        };
        

        现在,您可以自己进行初始化部分。或者,如果您同时需要两者,那么您可以同时保留它们。我的意思是您可以保留这 4 个变量并保留一个数组,然后在初始化时您可以自己显式设置内容。没有办法像你一样包装它。然后你像这样初始化

        struct MyStruct mystruct = {
           10.0, 
           { 5, 6, 7, 8 }
        };
        

        另外如果你想保持两组变量初始化为相同的值,你可以按照上面所示的相同方法进行。但考虑到其他两个不同的变量具有相同的值,这真的毫无意义。

        【讨论】:

          【解决方案5】:

          您可以在struct 中定义一个函数,该函数将params 数组初始化/设置为所需的值,该函数包含一个自引用self)到它的包含结构体。但是,params 数组中的值只有在调用此函数时才会“同步”...

          这个方法的一个例子是"this" pointer in C (not C++)

          #include <stdio.h>
          #include <stdlib.h>
          
          
              typedef struct MyStruct
              {
                  double  p;
                  double  x_min;
                  double  x_max;
                  double y_min;
                  double y_max;
                  double params[4] ;
                  void (*setParams)();
          
               }MyStruct;
          
              void setParams(MyStruct* self) {
                  self->params[0]= self->x_min;
                  self->params[1]= self->x_max;
                  self->params[2]= self->y_min;
                  self->params[3]= self->y_max;
              }
          
              int main (int argc, char * argv[])
              {
              MyStruct myStruct = {1.24, 2.0, 4.0, 2.0, 4.0, {0,0,0,0}, NULL };
              printf("%f, %f, %f, %f \n", myStruct.params[0], myStruct.params[1], myStruct.params[2], myStruct.params[3]  );
              setParams(&myStruct);
              printf("%f, %f, %f, %f \n", myStruct.params[0], myStruct.params[1], myStruct.params[2], myStruct.params[3]  );
          
              return 0;
              }
          

          但是要'同步'你必须打电话给setParams()

          【讨论】:

            【解决方案6】:

            假设您想要相同数据的 2 个不同副本,只需使用常识即可:

            typedef struct 
            {
              double x_min;
              double x_max;
              double y_min;
              double y_max;
            } xy_stuff;
            
            typedef struct 
            {
                double   p;
                xy_stuff xy;
                xy_stuff params;
            } Mystruct;
            
            ...
            
            Mystruct ms = 
            { 
              .p      = 1.0,
              .xy     = {1.0, 2.0, 3.0, 4.0},
              .params = {1.0, 2.0, 3.0, 4.0},
            };
            

            【讨论】:

              猜你喜欢
              • 2011-12-03
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-08-18
              • 2013-08-30
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多